首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

支付寶即時到賬:同步返回 vs 異步通知,別讓用戶關頁丟單

     編輯:程式設計綜合問答

核心誤區

以為用戶付款後**必須跳回商戶頁面(`return_url`)** 才能更新訂單狀態。若用戶關閉頁面、網絡斷開、跳轉失敗,訂單就會卡在「未處理」狀態。

正確架構:雙通道保障

通道參數觸發時機用途可靠性
同步跳轉return_url用戶付款成功後,支付寶頁面自動跳轉頁面提示「支付成功」、引導下載、跳轉會員中心低(用戶可關頁、攔截、網絡失敗)
異步通知notify_url支付寶服務器主動 POST 到商戶後台**核心業務邏輯**:驗簽、更新訂單狀態、發貨、發券、記賬高(支付寶重試機制、服務器對服務器)

標準處理流程

  1. 下單時:生成訂單,狀態 = WAIT_BUYER_PAY,保存 out_trade_no、notify_url、return_url。
  2. 用戶支付:支付寶處理付款。
  3. 異步通知(關鍵):
    • 支付寶 POST 到 notify_url,參數含 trade_status=TRADE_SUCCESS、out_trade_no、trade_no、sign 等。
    • 商戶後台:**驗證簽名**(RSA2)、**檢查 trade_status**、冪等處理**(防重複通知)、**更新訂單狀態**、**執行下游業務**。
    • 返回 success 純文本,支付寶收到才停止重試。
  4. 同步跳轉(輔助):用戶瀏覽器跳回 return_url,前端讀取參數展示成功頁,**不做狀態更新**,僅引導用戶。
  5. 主動查詢(兜底):若長時間未收到通知,定時任務調用 alipay.trade.query 查詢訂單狀態並同步。

關鍵代碼片段

// notify_url 處理器
public void notify(HttpServletRequest request, HttpServletResponse response) {
    Map params = buildParams(request); // 獲取所有參數
    String sign = params.remove("sign");
    String signType = params.get("sign_type");

    // 1. 驗簽
    if (!AlipaySignature.rsaCheckV1(params, alipayPublicKey, charset, signType)) {
        log.warn("簽名驗證失敗");
        return;
    }

    // 2. 業務校驗
    String outTradeNo = params.get("out_trade_no");
    String tradeStatus = params.get("trade_status");
    if (!"TRADE_SUCCESS".equals(tradeStatus) && !"TRADE_FINISHED".equals(tradeStatus)) {
        return; // 僅處理成功狀態
    }

    // 3. 冪等:檢查訂單當前狀態
    Order order = orderService.getByOutTradeNo(outTradeNo);
    if (order == null || order.getStatus() == OrderStatus.PAID) {
        printSuccess(response); // 已處理,直接成功
        return;
    }

    // 4. 更新狀態 & 業務
    orderService.paySuccess(order, params.get("trade_no"), params.get("gmt_payment"));

    // 5. 回應支付寶
    printSuccess(response);
}

private void printSuccess(HttpServletResponse response) {
    response.setContentType("text/plain");
    response.getWriter().write("success");
}

避坑清單

  • notify_url **必須是公網可訪問的 HTTP/HTTPS URL**,不能是 localhost、內網 IP、帶參數的動態頁(建議用靜態路徑 /api/alipay/notify)。
  • **驗簽用支付寶公鑰**,非商戶私鑰;推薦 RSA2 (SHA256WithRSA)。
  • **冪等性**:同一 out_trade_no 可能收到多次通知(重試、並發),必須用訂單狀態或分布式鎖防重。
  • **不依賴 `return_url` 做任何狀態變更**,它僅用於用戶體驗。
  • 支付寶通知**不保證順序**,退款通知可能比支付通知先到,業務邏輯需按 trade_status 判斷。

記住:**`notify_url` 才是訂單狀態的唯一真相來源**,`return_url` 只是給用戶看的體驗優化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved