支付寶電腦網站支付 alipay.trade.page.pay

只涉及支付接口 其餘接口沒有使用
支付寶官方文檔:https://docs.open.alipay.com/270/105899/
支付接口文檔 https://docs.open.alipay.com/270/alipay.trade.page.pay/
建議使用沙箱環境進行測試,沙箱接入 https://docs.open.alipay.com/200/105311java

具體實現請參考文檔和官方demoweb

注意事項:
請求支付頁面
  • 調用sdk的參數封裝成靜態變量,經過配置文件導入
  • 確認支付寶公鑰和商戶私鑰是否正確, 使用RSA2 簽名,回調地址必須外網能夠訪問到
  • 使用對象封裝請求參數
  • goods_detail類型爲 com.alipay.api.domain.GoodsDetail
  • JSONObject bizJson = JSONObject.fromObject(bizContent);轉爲json格式
  • 使用HttpServletResponse 輸出頁面,避免中文亂碼出現spring

    異步回調:
  • 參考文檔使用sdk驗證簽名
  • 注意驗證app_id 和 seller_id 等.
package com.youboy.order.controller.callback;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.youboy.alipay.constant.AlipayConfig;
import com.youboy.memberService.api.IQualificationService;
import com.youboy.order.api.hxpay.IBankDockingRecordsService;
import com.youboy.order.api.hxpay.IBankHxAccountService;
import com.youboy.order.exception.OrderWebOSException;
import com.youboy.pay.api.IPayService;
import com.youboy.pay.api.IPayWorker;
import com.youboy.pay.dto.PayBill;
import com.youboy.pay.dto.bank.BackCode;
import com.youboy.pay.dto.bank.GnetOrder;
import com.youboy.pay.exception.PayWebOSException;
import com.youboy.pay.utils.PaySta;
import com.youboy.shardSessionFilter.MemCacheManagerSpy;

/**
 * 支付寶回調
*/
@Controller
@RequestMapping("/zfb/callback")
public class ZfbPayBackOrderController {

    private final Logger logger = Logger.getLogger(ZfbPayBackOrderController.class);

    /**
     * 支付寶支付異步回調
     * @param model
     * @param request
     * @param response
     * @param session
     * @throws OrderWebOSException
     */
    @RequestMapping(value = "/payCallBack", method = RequestMethod.POST)
    @ResponseBody
    public String zfbPayCallBack(ModelMap model,
            HttpServletRequest request, HttpServletResponse response,
            HttpSession session) throws OrderWebOSException {
        boolean signVerified = checkRSA(request);
        if (!signVerified) { // 驗證失敗
            logger.error("不是支付寶的合法請求!");
            return "fail";
        }
        // 驗證通知是否有效
        boolean checkedTrustiness = checkedTrustiness(request);
        if (!checkedTrustiness) {
            logger.error("支付寶請求異常!");
            return "fail";
        }
        if ("TRADE_FINISHED".equals(trade_status) || "TRADE_SUCCESS".equals(trade_status)) {//TRADE_FINISHED交易成功並結束
            ......
        } /*else if (trade_status.equals("TRADE_SUCCESS")) {
            // 判斷該筆訂單是否在商戶網站中已經作過處理
            // 若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序
            // 若是有作過處理,不執行商戶的業務程序

            // 注意:
            // 付款完成後,支付寶系統發送該交易狀態通知
        }*/

         return "fail";
        
    }

    /**
     * 驗證是否爲支付寶的合法請求 --驗證簽名
     * @param request  獲取到的請求
     * @return
     */
    private boolean checkRSA(HttpServletRequest request) {
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> 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] + ",";
            }
            // 亂碼解決,這段代碼在出現亂碼時使用
            /*
             * try {
             * valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
             * } catch (UnsupportedEncodingException e) {
             * logger.error("回調接收參數亂碼",e);
             * }
             */
            params.put(name, valueStr);
        }
        logger.info("收到支付寶異步回調:");
        logger.info(params.toString());
        boolean signVerified = false;
        // 調用SDK驗證簽名
        try {
            signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset,
                    AlipayConfig.sign_type);
            return signVerified;
        } catch (AlipayApiException e) {
            // 調試用,寫文本函數記錄程序運行狀況是否正常
            String sWord = AlipaySignature.getSignCheckContentV1(params);
            AlipayConfig.logResult(sWord);
            logger.error("支付寶回調驗證簽名異常", e);
            return signVerified;
        }

    }

    // 驗證支付
    private boolean checkedTrustiness(HttpServletRequest request) {
        // 驗證成功
        String out_trade_no = "";
        String trade_status = "";
        String seller_id = "";
        String app_id = "";
        BigDecimal total_amount;
        try {
            // 商戶訂單號
            out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

            // 支付寶交易號
            // trade_no = new
            // String(request.getParameter("trade_no").getBytes("ISO-8859-1"),
            // "UTF-8");
            
            // 交易狀態
            trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
            // 支付訂單金額
            total_amount = new BigDecimal(
                    new String(request.getParameter("buyer_pay_amount").getBytes("ISO-8859-1"), "UTF-8"));
            // 賣家支付寶帳號
            seller_id = new String(request.getParameter("seller_id").getBytes("ISO-8859-1"), "UTF-8");
            app_id = new String(request.getParameter("app_id").getBytes("ISO-8859-1"), "UTF-8");

        } catch (UnsupportedEncodingException e) {
            logger.error("回調參數格式轉換異常(payid=" + out_trade_no + ")", e);
            return false;
        }
        if (!"TRADE_FINISHED".equals(trade_status) && !"TRADE_SUCCESS".equals(trade_status)) {
            logger.error("支付寶返回的交易狀態不正確(payid=" + out_trade_no + ")");
            return false;
        }
        // 2.驗證out_trade_no是否正確
        PayBill bill = new PayBill();
        try {
            bill = payService.find(out_trade_no).get(0);
        } catch (PayWebOSException e) {
            logger.error("paybill 查詢訂單狀況異常 (payid=" + out_trade_no + ")", e);
            return false;
        }
        // 3.判斷totalamount
        if (!total_amount.equals(bill.getAmount()) ) {
            logger.error("支付寶返回的訂單金額不正確(payid=" + out_trade_no + ")");
            return false;
        }
        // 支付狀態是否正確
        if (PaySta.Success.equals(bill.getStatus())) {
            logger.error("訂單狀態不正確(payid=" + out_trade_no + ")");
            return false;
        }
        // 判斷 seller_id
        if (!AlipayConfig.seller_id.equals(seller_id)) {
            logger.error("支付寶返回的seller_id不正確(payid=" + out_trade_no + ")");
            return false;
        }
        // 5.驗證app_id
        if (!AlipayConfig.app_id.equals(app_id)) {
            logger.error("支付寶返回的app_id不正確(payid=" + out_trade_no + ")");
            return false;
        }
        return true;

    }

}
相關文章
相關標籤/搜索