DedeCMS 支付功能集成完整教程
本教程将指导你如何在 Dedecms (织梦) 网站中集成支付宝支付功能,我们将以目前主流的 手机网站支付 (即手机H5支付) 为例,因为它兼容性好,可以方便地在PC和手机端调用。

(图片来源网络,侵删)
第一步:准备工作
在开始之前,请确保你已经准备好以下内容:
- 一个可正常访问的 Dedecms 网站:建议使用稳定版本,如 DedeCMS V5.7 或 V5.8。
- 一个支付宝商家/企业账号:个人账号无法申请开放平台接口。
- 一个已备案的域名:支付宝开放平台要求你的网站域名已完成备案。
- 基本的 PHP 和网站目录操作知识。
第二步:申请支付宝开放平台并获取配置信息
这是最关键的一步,你需要从支付宝后台获取你的应用ID和密钥。
-
登录支付宝开放平台
- 访问 https://open.alipay.com/ 并用你的商家账号登录。
-
创建应用
(图片来源网络,侵删)- 在控制台首页,点击 “创建应用”。
- 选择 “网页应用” 或 “移动应用”,然后点击 “立即创建”,对于手机网站支付,两者都可以,这里我们选择 “网页应用”。
- 填写应用名称(如“我的DedeCMS网站支付”),选择应用类目(如“网站与社区 -> 门户”),然后提交。
-
获取应用ID
- 应用创建成功后,进入应用详情页,在 “应用信息” 中,你可以找到
APPID,请务必复制并保存好这个APPID。
- 应用创建成功后,进入应用详情页,在 “应用信息” 中,你可以找到
-
生成应用私钥和获取支付宝公钥
- 在应用详情页,点击左侧菜单的 “接口加签方式”。
- 选择 “密钥” 模式(推荐)。
- 点击 “生成密钥”,系统会弹出一个工具。
- 下载密钥工具:根据你的操作系统下载对应的密钥生成工具。
- 生成密钥对:
- 打开下载的密钥工具。
- 点击 “生成密钥”,工具会自动生成一对密钥:应用私钥 和 应用公钥。
- 重要:
应用私钥是你自己的,必须严格保密,不能泄露。应用公钥是要提交给支付宝的。
- 上传公钥:将生成的 应用公钥 复制到支付宝页面的文本框中,点击 “保存”。
-
签约产品
- 在应用详情页,点击左侧菜单的 “产品绑定”。
- 找到并勾选 “手机网站支付” 产品,然后点击 “立即申请”,按照提示完成签约,通常个人商家签约此产品需要提供一些资质信息,审核通过后即可使用。
-
配置应用密钥
(图片来源网络,侵删)- 回到 “接口加签方式” 页面,你应该能看到
APPID和支付宝公钥已经配置好了。 - 你需要将
应用私钥填入 Dedecms 的配置文件中。
- 回到 “接口加签方式” 页面,你应该能看到
第三步:下载并集成支付宝 SDK
为了方便开发者调用支付宝接口,官方提供了软件开发工具包。
-
下载 SDK
- 访问支付宝官方 SDK 仓库:https://github.com/alipay/alipay-sdk-php-all
- 下载最新的
zip包并解压。
-
上传 SDK 到网站
- 在你的 Dedecms 网站根目录下,创建一个名为
alipay的文件夹。 - 将解压后的 SDK 包中的以下核心文件和文件夹上传到
/alipay/目录下:AopSdk.php(核心 SDK 类文件)lib/(文件夹,包含各种请求和响应模型)top(文件夹,包含一些基础类)composer.json(依赖管理文件)
你的目录结构应该类似:
/wwwroot/your-dede-site/ ├── /alipay/ │ ├── AopSdk.php │ ├── composer.json │ ├── /lib/ │ └── /top/ └── ... (其他Dede文件) - 在你的 Dedecms 网站根目录下,创建一个名为
第四步:修改 Dedecms 文件以实现支付功能
我们需要修改两个地方:一个用于生成支付链接,另一个用于处理支付后的异步和同步回调。
创建支付请求页面 (pay.php)
这个页面通常在用户点击“去支付”按钮后跳转到这里,用于向支付宝发起支付请求。
在你的网站根目录下创建一个新文件 pay.php,并将以下代码复制进去。
<?php
require_once (dirname(__FILE__) . "/include/common.inc.php");
require_once 'alipay/AopSdk.php';
// 1. 获取订单信息 (这里需要根据你的业务逻辑来获取)
// 假设订单ID是从URL参数传递过来的, pay.php?order_id=12345
$orderId = isset($_GET['order_id']) ? trim($_GET['order_id']) : '';
if (empty($orderId)) {
die('订单ID不能为空');
}
// 从你的订单表里查询出订单总金额、商品名称等信息
// !!! 这是示例代码,请务必替换成你自己的数据库查询逻辑 !!!
// $orderAmount = 0.01; // 单位:元
// $orderName = 'DedeCMS商品订单';
// 假设你的订单表是 `dede_archives` 或自定义的表
// $row = $dsql->GetOne("SELECT money,title FROM `#@__your_order_table` WHERE order_id = '{$orderId}'");
// if (!$row) {
// die('订单不存在');
// }
// $orderAmount = $row['money'];
// $orderName = $row['title'];
// 为了演示,我们使用固定值
$orderAmount = 0.01; // 测试金额,单位:元
$orderName = 'DedeCMS测试订单';
// 2. 配置支付宝参数
$aop = new \AopClient();
$aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
$aop->appId = "你的APPID"; // 替换成你的APPID
$aop->rsaPrivateKey = "你的应用私钥"; // 替换成你自己的应用私钥(从支付宝工具生成并保存的那串)
$aop->format = "json";
$aop->charset = "UTF-8";
$aop->signType = "RSA2";
$aop->alipayrsaPublicKey = "支付宝公钥"; // 替换成你在支付宝后台配置的支付宝公钥
// 3. 设置请求参数
$request = new \AlipayTradeWapPayRequest();
$request->setReturnUrl("http://你的域名.com/pay_return.php"); // 同步回调地址
$request->setNotifyUrl("http://你的域名.com/pay_notify.php"); // 异步回调地址
// 构造请求参数
// biz_content 是一个JSON字符串,包含订单详情
$bizContent = json_encode([
"out_trade_no" => $orderId, // 商户网站唯一订单号
"total_amount" => $orderAmount, // 订单金额
"subject" => $orderName, // 订单标题
"product_code" => "QUICK_WAP_WAY" // 固定值,手机网站支付产品码
], JSON_UNESCAPED_UNICODE);
$request->setBizContent($bizContent);
// 4. 发起请求
$response = $aop->pageExecute($request, 'GET');
// 5. 直接输出支付宝的表单和JS,页面会自动跳转到支付宝收银台
echo $response;
?>
修改说明:
require_once "include/common.inc.php": 引入DedeCMS的核心文件,以便使用$dsql等数据库操作对象。$orderId: 这是你从你的业务逻辑中获取的唯一订单号,你需要根据你的网站实际情况(比如从会员中心或订单详情页传递过来)来修改获取方式。$orderAmount和$orderName: 这里应该是从数据库查询出来的订单金额和商品名称。请务必修改这部分代码,连接你自己的订单表。$aop->appId和密钥: 将第二步中获取到的APPID、应用私钥和支付宝公钥填入。setReturnUrl和setNotifyUrl: 这两个URL是支付成功后支付宝会回调你的地址,我们需要在下一步创建这两个文件。
创建支付回调页面
支付宝支付完成后,会通过两个回调通知你的网站。
a. 同步回调页面 (pay_return.php)
用户在支付宝支付成功并点击“返回商家”后,会跳转到这里,这个页面主要用于用户体验,显示“支付成功,正在跳转...”。
<?php
require_once (dirname(__FILE__) . "/include/common.inc.php");
require_once 'alipay/AopSdk.php';
// 1. 实例化SDK
$aop = new \AopClient();
$aop->alipayrsaPublicKey = "支付宝公钥"; // 替换成你的支付宝公钥
// 2. 验证同步请求的签名
// 注意:同步回调的参数是通过GET方式传递的
$flag = $aop->rsaCheckV1($_GET, null, "RSA2");
if ($flag) {
// 验证成功
// 1. 获取商户订单号
$outTradeNo = $_GET['out_trade_no'];
// 2. 根据订单号查询你的订单,并更新订单状态为“已支付”
// !!! 这是示例代码,请务必替换成你自己的逻辑 !!!
// $dsql->ExecuteNoneQuery("UPDATE `#@__your_order_table` SET status = 'paid', pay_time = NOW() WHERE order_id = '{$outTradeNo}'");
// 3. 显示支付成功页面
echo '<h1>支付成功!</h1>';
echo '<p>订单号:' . htmlspecialchars($outTradeNo) . '</p>';
echo '<p>正在跳转到订单详情页...<p>';
// 可以使用JS实现页面跳转
echo '<script>window.location.href="/member/order.php?order_id=' . $outTradeNo . '";</script>';
} else {
// 验证失败
echo '<h1>支付验证失败!</h1>';
echo '<p>请不要关闭此页面,请联系客服。</p>';
}
?>
b. 异步回调页面 (pay_notify.php)
这是最最重要的部分,支付结果最终以支付宝异步通知为准,你的服务器需要接收这个通知,并处理订单状态。
<?php
require_once (dirname(__FILE__) . "/include/common.inc.php");
require_once 'alipay/AopSdk.php';
// 1. 实例化SDK
$aop = new \AopClient();
$aop->alipayrsaPublicKey = "支付宝公钥"; // 替换成你的支付宝公钥
// 2. 验证异步通知的签名
// 注意:异步回调的参数是通过POST方式传递的
$flag = $aop->rsaCheckV1($_POST, null, "RSA2");
// 3. 处理逻辑
if ($flag) {
// 验证成功,开始处理业务逻辑
// 获取关键参数
$outTradeNo = $_POST['out_trade_no']; // 商户订单号
$tradeNo = $_POST['trade_no']; // 支付宝交易号
$tradeStatus = $_POST['trade_status']; // 交易状态
// 根据交易状态处理
if ($tradeStatus == 'TRADE_SUCCESS' || $tradeStatus == 'TRADE_FINISHED') {
// !!! 这是核心业务逻辑,请务必仔细处理 !!!
// 1. 检查你的订单是否已经是“已支付”状态,防止重复处理(非常重要!)
// $row = $dsql->GetOne("SELECT status FROM `#@__your_order_table` WHERE order_id = '{$outTradeNo}'");
// if ($row && $row['status'] == 'paid') {
// // 订单已处理,直接返回 'success' 给支付宝
// echo 'success';
// exit;
// }
// 2. 更新订单状态为“已支付”,并记录支付宝交易号和支付时间
// $sql = "UPDATE `#@__your_order_table` SET
// status = 'paid',
// alipay_trade_no = '{$tradeNo}',
// pay_time = NOW()
// WHERE order_id = '{$outTradeNo}'";
// $dsql->ExecuteNoneQuery($sql);
// 3. (可选) 发送邮件、短信通知用户,或者触发发货流程
// ...
// 4. 返回 'success' 给支付宝,表示通知接收成功
echo 'success';
exit;
}
} else {
// 验证失败
// 记录错误日志,方便排查
file_put_contents('alipay_notify_error.log', date('Y-m-d H:i:s') . " - 验证失败\n" . print_r($_POST, true), FILE_APPEND);
echo 'fail';
}
?>
异步回调页面关键点:
- 签名验证:必须先验证签名,确保通知是支付宝官方发送的。
- 幂等性处理:在更新订单状态前,务必检查订单是否已经处理过,如果已经处理过,直接返回
success,避免重复发货或重复扣款。 - 返回
success:无论处理成功还是失败(只要验证通过),都必须向支付宝返回一个success字符串,告诉支付宝“我收到通知了”,否则,支付宝会认为你没有收到通知,并定时重发通知。 - 错误日志:验证失败时,一定要记录日志,方便排查问题。
第五步:测试支付 (使用支付宝沙箱环境)
在正式上线前,一定要使用支付宝的沙箱环境进行测试,确保流程无误。
- 登录支付宝开放平台 -> 进入你的应用详情页。
- 点击左侧菜单的 “沙箱环境”。
- 开启沙箱环境开关。
- 你会看到沙箱环境的
APPID和沙箱环境密钥。 - 修改你的
pay.php文件:- 将
$aop->appId和密钥替换成 沙箱环境 的APPID和 沙箱密钥。 - 非常重要:沙箱环境的密钥也需要在沙箱环境的“接口加签方式”里生成和配置。
- 将
- 获取沙箱账号:在沙箱环境页面,你可以找到两个测试账号:一个买家账号(用于扫码支付),一个卖家账号(用于查看收款)。
- 访问你的支付页面:用你的网站访问
pay.php?order_id=test123,会跳转到支付宝收银台,你可以使用沙箱买家账号扫码支付,整个过程不会产生真实资金。
第六步:部署到生产环境
测试通过后,即可切换到生产环境。
- 关闭沙箱环境。
- 修改
pay.php文件:- 将
$aop->appId和密钥替换回 生产环境 的真实APPID和密钥。
- 将
- 确保回调地址可被支付宝访问:
pay_return.php和pay_notify.php必须可以通过公网IP和域名访问。- 如果你使用的是本地开发环境,可以使用内网穿透工具(如花生壳、ngrok)将本地端口映射到公网,以便支付宝能回调成功。
- 在生产服务器上,确保服务器的防火墙和云服务商(如阿里云、腾讯云)的安全组策略放行了80和443端口。
- 再次完整测试:使用真实支付宝账号进行一笔小额测试支付,确保一切正常。
总结与注意事项
- 安全第一:永远不要将你的私钥泄露给任何人。
- 幂等性:异步回调处理逻辑中,一定要有防止重复处理的机制。
- 日志记录:无论是支付请求还是回调,都建议记录详细的日志,方便排查问题。
- 用户体验:同步回调页面应简洁明了,并尽快跳转回用户的会员中心或订单详情页。
- 错误处理:对可能出现的异常情况(如网络中断、数据库连接失败等)进行捕获和处理。
这份教程涵盖了从申请到部署的全过程,希望能帮助你成功在 Dedecms 中集成支付宝支付功能,如果在操作中遇到具体问题,可以提供错误信息,我会尽力帮你分析。
