支付寶 接口對接


 

項目結構 :

 

下單核心代碼:

package com.alipay.pay.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.demo.trade.model.builder.AlipayTradeQueryRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FQueryResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.pay.config.AlipayConfig;
import com.alipay.pay.model.Order;

/**
 * 支付寶-電腦網站支付. 
 * 注意 下單頁面可以加一個ajax輪詢進行 訂單查詢避免長時間等待
 * <p>
 * 電腦網站支付 https://docs.open.alipay.com/270/105898/
 *
 * @author zhourong
 * @version 1.0
 * @since 2018/12/27
 */
@Controller
@RequestMapping("/alipay/page")
public class PayController {

    
    @Autowired
    private AlipayConfig alipayConfig;//支付寶查詢接口初始化
    
    @Autowired
    private AlipayClient alipayClient;//初始化 相關配置
    
    @Autowired
    private AlipayTradeService tradeService;
    
    private final Logger log = LoggerFactory.getLogger(PayController.class);

    @GetMapping("/gotoPayPage")
    public void gotoPayPage(HttpServletResponse response,Order order) throws AlipayApiException, IOException {
        
        //下單 插入數據庫
        //一系列業務判斷
        //insert into order ......
        //正常業務流程會把 支付接口抽出來 
        
        // 設置請求參數
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        // 同步通知地址:支付成功后頁面自動跳轉到傳值地址中
        alipayRequest.setReturnUrl("http://zhouixi.free.idcfengye.com/alipay/page/returnUrl");
        // 異步通知地址:支付成功生成之后會post返回訂單信息詳情到該地址,用於商家做業務邏輯處理
        alipayRequest.setNotifyUrl("http://zhouixi.free.idcfengye.com/alipay/page/NotifyUrl");

        // 商戶訂單號,商戶網站訂單系統中唯一訂單號,必填
        String out_trade_no = order.getOutTradeNo();
        // 付款金額,必填
        String total_amount = order.getTotalAmount();
        // 訂單名稱,必填
        String subject = order.getSubject();
        // 商品描述,可空
        String body = "用戶訂購商品個數:1";

        // 該筆訂單允許的最晚付款時間,逾期將關閉交易。取值范圍:1m~15d。m-分鍾,h-小時,d-天,1c-當天(1c-當天的情況下,無論交易何時創建,都在0點關閉)。
        // 該參數數值不接受小數點, 如 1.5h,可轉換為 90m。
        String timeout_express = "5m";

        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," + "\"total_amount\":\"" + total_amount
                + "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + body + "\"," + "\"timeout_express\":\""
                + timeout_express + "\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        /**
         * BizContent傳值模式 alipayRequest.setBizContent("{\"out_trade_no\":\""+
         * out_trade_no +"\"," + "\"total_amount\":\""+ total_amount +"\"," +
         * "\"subject\":\""+ subject +"\"," + "\"qr_pay_mode\":\"4\"," +
         * "\"timeout_express\":\"1m\"," + "\"passback_params2\":\""+ passback_params2
         * +"\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
         * 
         **/
        // get請求方式,返回http鏈接
        // AlipayTradePagePayResponse respose = alipayClient.pageExecute(alipayRequest,
        // "get");

        // post請求方式,返回from表單
        AlipayTradePagePayResponse aliResponse = alipayClient.pageExecute(alipayRequest);
        
        // 打印請求信息
        String html = aliResponse.getBody();
        response.setContentType("text/html;charset=" + alipayConfig.getCharset());
        response.getWriter().write(html);
        response.getWriter().flush();
        response.getWriter().close();
    }

    @RequestMapping("/returnUrl")
    public String returnUrl(HttpServletRequest request, HttpServletResponse response)
            throws UnsupportedEncodingException, AlipayApiException {
        response.setContentType("text/html;charset=" + "utf-8");
        boolean verifyResult = this.checkParam(request);
        if (verifyResult) {
            // 驗證成功
            //添加自己的業務。。。進行業務核對
            // 商戶訂單號
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            // 支付寶交易號
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            
            // (必填) 商戶訂單號,通過此商戶訂單號查詢當面付的交易狀態
            AlipayTradeQueryRequestBuilder builder = new AlipayTradeQueryRequestBuilder()
                    .setOutTradeNo(out_trade_no);
            AlipayF2FQueryResult result = tradeService.queryTradeResult(builder);
            System.out.println(result.getTradeStatus());
            return "success";
        } else {
            return "fail";
        }
    }

    @RequestMapping("/notifyUrl")
    public String NotifyUrl(HttpServletRequest request, HttpServletResponse response)
            throws UnsupportedEncodingException, AlipayApiException {
        response.setContentType("text/html;charset=" + "utf-8");

        boolean verifyResult = this.checkParam(request);
        if (verifyResult) {
            // 驗證成功
            //添加自己的業務。。。進行業務核對
            // 商戶訂單號
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            // 支付寶交易號
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            
            // (必填) 商戶訂單號,通過此商戶訂單號查詢當面付的交易狀態
            AlipayTradeQueryRequestBuilder builder = new AlipayTradeQueryRequestBuilder()
                    .setOutTradeNo(out_trade_no);
            AlipayF2FQueryResult result = tradeService.queryTradeResult(builder);
            System.out.println(result.getTradeStatus());
            return "success";
        } else {
            return "fail";
        }
    }

    /**
     * 校驗簽名
     * 
     * @param request
     * @return
     */
    private boolean checkParam(HttpServletRequest request) {
        // https://docs.open.alipay.com/54/106370  官方文檔
        // 獲取支付寶POST過來反饋信息
        Map<String, String> params = new HashMap<>();
        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] + ",";
            }
            params.put(name, valueStr);
        }

        try {
            boolean verifyResult = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(),
                    alipayConfig.getCharset(), alipayConfig.getSignType());
            return verifyResult;
        } catch (AlipayApiException e) {
            log.debug("verify sigin error, exception is:{}", e);
            return false;
        }
    }
}

效果:

 

支付只能用支付寶提供的沙箱帳號及沙箱app

不然會提示二維碼過期。

問題總結:

1.AlipayTradeServiceImpl gatewayUrl should not be NULL!

  支付寶查詢接口 AlipayTradeServiceImpl  沒有初始化

2.驗簽失敗 :返回false

   使用支付寶公鑰沙箱應用里面的公鑰,不能使用工具生成的公鑰

3.支付過程中,一直要做訂單號重復過濾。不然。支付寶生成不了二維碼頁面。

4.支付過程中,支付接口有自動過濾重復支付。盡量把業務處理在自己的接口里面。避免重復支付。

5.支付寶回調接口一定要是外網可以直接訪問的。支付成功之后。支付寶會自動回接回調接口推送相關信息過來 。可以做一些業務處理。比如說:支付訂單的檢驗,自己系統的業務檢驗。入庫等

git:https://gitee.com/xxoo0_297/alipay.git


免責聲明!

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



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