支付寶「即時到賬」(`create_direct_pay_by_user`) 適用於電商下單即付場景。官方 PHP SDK 目錄結構:
alipay-sdk/ ├── lib/ │ ├── alipay_core.function.php # 核心工具函數 │ ├── alipay_md5.function.php # MD5 簽名 │ ├── alipay_submit.class.php # 請求構造/提交 │ └── alipay_notify.class.php # 通知驗證/處理 ├── alipay.config.php # 合作伙伴配置 ├── alipayapi.php # 支付入口(生成表單跳轉) ├── return_url.php # 同步跳轉返回頁 ├── notify_url.php # 異步通知處理頁 ├── cacert.pem # SSL CA 證書 └── log.txt # 日誌文件
<?php
$alipay_config = [
'partner' => '2088xxxxxxxxxx', // 合作身份者ID
'seller_id' => 'seller@email.com', // 賣家支付寶賬號
'key' => 'xxxxxxxxxxxxxxxxxxxx', // 安全檢驗碼 (MD5 key)
'sign_type' => 'MD5', // 簽名方式
'input_charset' => 'utf-8',
'cacert' => getcwd() . '/cacert.pem',
'transport' => 'http', // http/https
'service' => 'create_direct_pay_by_user',
'payment_type' => '1', // 商品購買
'notify_url' => 'https://your.domain/notify_url.php', // 必須外網可訪問
'return_url' => 'https://your.domain/return_url.php',
'anti_phishing_key' => '', // 防釣魚時間戳(可選)
'exter_invoke_ip' => '', // 客戶端IP(可選)
];
關鍵點: `notify_url` / `return_url` 必須為**完整 HTTP/HTTPS 域名**,不能攜帶自定義查詢參數,且服務器需對外網開放 80/443 端口。
<?php
require_once 'alipay.config.php';
require_once 'lib/alipay_submit.class.php';
// 1. 獲取業務參數(實際從訂單系統獲取)
$out_trade_no = $_POST['WIDout_trade_no']; // 商戶訂單號,唯一
$subject = $_POST['WIDsubject']; // 訂單標題
$total_fee = $_POST['WIDtotal_fee']; // 金額(元),如 0.01
$body = $_POST['WIDbody']; // 商品描述
// 2. 構造請求參數數組
$parameter = [
'service' => $alipay_config['service'],
'partner' => $alipay_config['partner'],
'seller_id' => $alipay_config['seller_id'],
'payment_type' => $alipay_config['payment_type'],
'notify_url' => $alipay_config['notify_url'],
'return_url' => $alipay_config['return_url'],
'out_trade_no' => $out_trade_no,
'subject' => $subject,
'total_fee' => $total_fee,
'body' => $body,
'_input_charset' => strtolower(trim($alipay_config['input_charset'])),
// 其它業務擴展參數參考《支付寶開放平台文檔》
];
// 3. 構造自動提交表單(GET 跳轉)
$alipaySubmit = new AlipaySubmit($alipay_config);
$html_text = $alipaySubmit->buildRequestForm($parameter, 'get', '確認支付');
echo $html_text; // 輸出包含隱藏字段的
特性: GET 方式、用戶可見、近乎實時、**只觸發一次**、可本地調試。
<?php
require_once 'alipay.config.php';
require_once 'lib/alipay_notify.class.php';
$alipayNotify = new AlipayNotify($alipay_config);
$verify_result = $alipayNotify->verifyReturn();
if ($verify_result) {
// 驗證成功
$out_trade_no = $_GET['out_trade_no'];
$trade_no = $_GET['trade_no'];
$trade_status = $_GET['trade_status'];
$total_fee = $_GET['total_fee'];
if ($trade_status === 'TRADE_FINISHED' || $trade_status === 'TRADE_SUCCESS') {
// 判斷該訂單是否已處理(防重複)
if (!orderProcessed($out_trade_no)) {
processOrder($out_trade_no, $trade_no, $total_fee);
}
echo "支付成功,訂單號: $out_trade_no";
} else {
echo "交易狀態: $trade_status";
}
} else {
echo "簽名驗證失敗,數據可能被篡改";
}
特性: POST 方式、用戶不可見、**重試機制**(失敗間隔遞增至 48h)、**必須外網調試**、響應 `success`/`fail` 文本控制重試。
<?php
require_once 'alipay.config.php';
require_once 'lib/alipay_notify.class.php';
// 1. 空白頁面,無任何 HTML/空白字符
// 2. 實例化驗證
$alipayNotify = new AlipayNotify($alipay_config);
$verify_result = $alipayNotify->verifyNotify();
if ($verify_result) {
// 3. 解析業務參數
$out_trade_no = $_POST['out_trade_no'];
$trade_no = $_POST['trade_no'];
$trade_status = $_POST['trade_status'];
$total_fee = $_POST['total_fee'];
$buyer_email = $_POST['buyer_email'];
// 4. 業務邏輯(冪等性關鍵)
if ($trade_status === 'TRADE_SUCCESS' || $trade_status === 'TRADE_FINISHED') {
if (!orderProcessed($out_trade_no)) { // 唯一索引/Redis 分布式鎖
$success = processOrder($out_trade_no, $trade_no, $total_fee, $buyer_email);
if ($success) {
echo "success"; // 告訴支付寶處理完成,停止重試
exit;
}
} else {
echo "success"; // 已處理,直接成功
exit;
}
}
echo "fail"; // 業務失敗,支付寶將按策略重試
} else {
echo "fail"; // 驗簽失敗
}
| 場景 | 風險 | 對策 |
|---|---|---|
| 用戶支付成功,關閉頁面未跳回 return_url | 同步頁邏輯未執行 | 異步通知作為**最終一致性保障** |
| 異步通知處理失敗(DB死鎖、網絡抖動) | 支付寶重試 48h 後放棄 | 業務邏輯冪等 + 手動補單介面 + 定時對賬任務 |
| 同步頁與異步通知並發處理同一訂單 | 重複發貨/加款 | 數據庫唯一索引 `out_trade_no` + `INSERT IGNORE` / `ON DUPLICATE KEY UPDATE` |
支付寶已推出新版 API(`alipay.trade.page.pay`),基於 RSA2 簽名、JSON 格式、網關統一。舊版 MD5/表單跳轉模式**仍可用但不再維護**,新項目建議直接接入 新版 SDK,享受更安全的加密、更豐富的營銷工具、更完善的錯誤碼體系。