# 如何用PHP實現支付寶支付
## 前言
在當今電子商務蓬勃發展的時代,電子支付已成為商業交易中不可或缺的一環。作為國內領先的第三方支付平臺,支付寶憑借其便捷性和安全性,成為眾多企業和開發者的首選支付解決方案。本文將詳細介紹如何使用PHP語言實現支付寶支付功能,涵蓋從準備工作到代碼實現的完整流程。
## 一、準備工作
### 1.1 注冊支付寶開發者賬號
首先需要訪問[支付寶開放平臺](https://open.alipay.com/)并完成開發者賬號注冊。注冊流程包括:
1. 使用企業支付寶賬號登錄
2. 完成實名認證
3. 簽署開放平臺協議
### 1.2 創建應用并獲取密鑰
成功注冊后,需要創建應用并配置相關參數:
```php
// 應用基本配置示例
$config = [
'app_id' => '2021000123456789', // 你的應用ID
'merchant_private_key' => '你的商戶私鑰',
'alipay_public_key' => '支付寶公鑰',
'notify_url' => 'https://yourdomain.com/notify.php', // 異步通知地址
'return_url' => 'https://yourdomain.com/return.php', // 同步跳轉地址
'charset' => 'UTF-8',
'sign_type' => 'RSA2',
'gateway_url' => 'https://openapi.alipay.com/gateway.do',
];
支付寶使用RSA2簽名算法確保交易安全,生成密鑰對的步驟如下:
openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem
支付寶提供了官方PHP SDK,可以通過Composer安裝:
composer require alipay/alipay-easysdk
或者手動下載SDK并引入:
require_once '/path/to/alipay-sdk/AopSdk.php';
use Alipay\EasySDK\Kernel\Config;
use Alipay\EasySDK\Kernel\Factory;
$options = new Config();
$options->protocol = 'https';
$options->gatewayHost = 'openapi.alipay.com';
$options->signType = 'RSA2';
$options->appId = '你的APPID';
$options->merchantPrivateKey = '你的私鑰';
$options->alipayPublicKey = '支付寶公鑰';
$options->notifyUrl = 'https://yourdomain.com/notify.php';
Factory::setOptions($options);
電腦網站支付適用于PC端網頁場景,實現代碼如下:
public function createWebPayment($orderId, $amount, $subject)
{
try {
$result = Factory::payment()->page()
->pay($subject, $orderId, $amount, 'https://yourdomain.com/return.php');
return $result->body; // 返回支付表單
} catch (Exception $e) {
// 異常處理
return false;
}
}
針對移動端優化的支付方案:
public function createWapPayment($orderId, $amount, $subject)
{
try {
$result = Factory::payment()->wap()
->pay($subject, $orderId, $amount, 'https://yourdomain.com/return.php', 'https://yourdomain.com/cancel.php');
return $result->body;
} catch (Exception $e) {
return false;
}
}
對于原生APP應用,需要調用支付寶APP支付:
public function createAppPayment($orderId, $amount, $subject)
{
try {
$result = Factory::payment()->app()
->pay($subject, $orderId, $amount);
return $result->body;
} catch (Exception $e) {
return false;
}
}
用戶支付完成后,支付寶會同步跳轉到return_url:
public function handleReturn()
{
$request = $_GET;
try {
$result = Factory::payment()->common()->verifyNotify($request);
if ($result) {
// 驗證簽名成功
$tradeStatus = $request['trade_status'];
if ($tradeStatus == 'TRADE_SUCCESS' || $tradeStatus == 'TRADE_FINISHED') {
// 支付成功邏輯
$orderId = $request['out_trade_no'];
$this->updateOrderStatus($orderId, 'paid');
return redirect('/success.php');
}
}
return redirect('/failure.php');
} catch (Exception $e) {
// 異常處理
return redirect('/error.php');
}
}
支付寶服務器會異步發送支付結果到notify_url:
public function handleNotify()
{
$request = $_POST;
try {
$result = Factory::payment()->common()->verifyNotify($request);
if ($result) {
$tradeStatus = $request['trade_status'];
if ($tradeStatus == 'TRADE_SUCCESS' || $tradeStatus == 'TRADE_FINISHED') {
// 處理訂單狀態
$orderId = $request['out_trade_no'];
$this->updateOrderStatus($orderId, 'paid');
// 記錄交易信息
$this->logTransaction($request);
// 必須返回success表示處理成功
echo "success";
return;
}
}
echo "failure";
} catch (Exception $e) {
// 記錄錯誤日志
error_log($e->getMessage());
echo "failure";
}
}
public function queryOrder($orderId)
{
try {
$result = Factory::payment()->common()->query($orderId);
if ($result->code == "10000") {
return [
'status' => $result->tradeStatus,
'amount' => $result->totalAmount,
'time' => $result->sendPayDate
];
}
return false;
} catch (Exception $e) {
return false;
}
}
public function refundOrder($orderId, $amount, $reason = '')
{
try {
$result = Factory::payment()->common()->refund($orderId, $amount, $reason);
if ($result->code == "10000") {
return $result->refundFee;
}
return false;
} catch (Exception $e) {
return false;
}
}
public function closeOrder($orderId)
{
try {
$result = Factory::payment()->common()->close($orderId);
return $result->code == "10000";
} catch (Exception $e) {
return false;
}
}
public function handleNotify()
{
// ...驗證邏輯...
// 檢查是否已處理過該通知
$notifyId = $request['notify_id'];
if ($this->isNotifyProcessed($notifyId)) {
echo "success";
return;
}
// ...處理邏輯...
// 記錄已處理的通知ID
$this->markNotifyAsProcessed($notifyId);
}
class AlipayLogger
{
public static function log($data, $type = 'info')
{
$logData = [
'time' => date('Y-m-d H:i:s'),
'type' => $type,
'data' => $data
];
file_put_contents(
'/var/log/alipay_'.date('Ymd').'.log',
json_encode($logData).PHP_EOL,
FILE_APPEND
);
}
}
可能原因: - 公鑰私鑰不匹配 - 參數編碼不一致 - 簽名類型配置錯誤
解決方案: 1. 檢查密鑰是否正確配置 2. 確保所有參數使用UTF-8編碼 3. 確認sign_type設置為RSA2
排查步驟: 1. 檢查服務器是否能外網訪問 2. 驗證notify_url是否已正確配置 3. 查看支付寶商戶中心的通知日志
處理建議: - 同步通知僅用于展示結果,業務邏輯應依賴異步通知 - 實現主動查詢機制作為補償
通過本文的詳細講解,您應該已經掌握了使用PHP實現支付寶支付的核心技術。實際開發中,請根據業務需求選擇合適的支付產品,并嚴格遵守支付寶的接口規范和安全要求。支付系統作為電商平臺的核心組件,其穩定性和安全性至關重要,建議在正式上線前進行充分的測試和壓力測試。
隨著支付寶API的不斷更新,開發者應及時關注官方文檔的變更,保持代碼的兼容性。希望本文能為您的支付系統開發提供有價值的參考。
擴展閱讀: - 支付寶官方開發文檔 - PHP安全編程指南 - 電子商務支付系統設計模式 “`
這篇文章提供了從基礎到進階的完整實現方案,涵蓋了電腦網站支付、手機網站支付和APP支付三種常見場景,并包含了安全實踐和問題排查等實用內容。實際開發時,請根據您的具體業務需求調整實現細節。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。