DedeCMS 支付功能集成完整教程

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

dedecms 支付 教程
(图片来源网络,侵删)

第一步:准备工作

在开始之前,请确保你已经准备好以下内容:

  1. 一个可正常访问的 Dedecms 网站:建议使用稳定版本,如 DedeCMS V5.7 或 V5.8。
  2. 一个支付宝商家/企业账号:个人账号无法申请开放平台接口。
  3. 一个已备案的域名:支付宝开放平台要求你的网站域名已完成备案。
  4. 基本的 PHP 和网站目录操作知识

第二步:申请支付宝开放平台并获取配置信息

这是最关键的一步,你需要从支付宝后台获取你的应用ID和密钥。

  1. 登录支付宝开放平台

  2. 创建应用

    dedecms 支付 教程
    (图片来源网络,侵删)
    • 在控制台首页,点击 “创建应用”
    • 选择 “网页应用”“移动应用”,然后点击 “立即创建”,对于手机网站支付,两者都可以,这里我们选择 “网页应用”
    • 填写应用名称(如“我的DedeCMS网站支付”),选择应用类目(如“网站与社区 -> 门户”),然后提交。
  3. 获取应用ID

    • 应用创建成功后,进入应用详情页,在 “应用信息” 中,你可以找到 APPID,请务必复制并保存好这个 APPID
  4. 生成应用私钥和获取支付宝公钥

    • 在应用详情页,点击左侧菜单的 “接口加签方式”
    • 选择 “密钥” 模式(推荐)。
    • 点击 “生成密钥”,系统会弹出一个工具。
    • 下载密钥工具:根据你的操作系统下载对应的密钥生成工具。
    • 生成密钥对
      • 打开下载的密钥工具。
      • 点击 “生成密钥”,工具会自动生成一对密钥:应用私钥应用公钥
      • 重要应用私钥 是你自己的,必须严格保密,不能泄露。应用公钥 是要提交给支付宝的。
    • 上传公钥:将生成的 应用公钥 复制到支付宝页面的文本框中,点击 “保存”
  5. 签约产品

    • 在应用详情页,点击左侧菜单的 “产品绑定”
    • 找到并勾选 “手机网站支付” 产品,然后点击 “立即申请”,按照提示完成签约,通常个人商家签约此产品需要提供一些资质信息,审核通过后即可使用。
  6. 配置应用密钥

    dedecms 支付 教程
    (图片来源网络,侵删)
    • 回到 “接口加签方式” 页面,你应该能看到 APPID支付宝公钥 已经配置好了。
    • 你需要将 应用私钥 填入 Dedecms 的配置文件中。

第三步:下载并集成支付宝 SDK

为了方便开发者调用支付宝接口,官方提供了软件开发工具包。

  1. 下载 SDK

  2. 上传 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 文件以实现支付功能

我们需要修改两个地方:一个用于生成支付链接,另一个用于处理支付后的异步和同步回调。

创建支付请求页面 (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应用私钥支付宝公钥 填入。
  • setReturnUrlsetNotifyUrl: 这两个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 字符串,告诉支付宝“我收到通知了”,否则,支付宝会认为你没有收到通知,并定时重发通知。
  • 错误日志:验证失败时,一定要记录日志,方便排查问题。

第五步:测试支付 (使用支付宝沙箱环境)

在正式上线前,一定要使用支付宝的沙箱环境进行测试,确保流程无误。

  1. 登录支付宝开放平台 -> 进入你的应用详情页。
  2. 点击左侧菜单的 “沙箱环境”
  3. 开启沙箱环境开关。
  4. 你会看到沙箱环境的 APPID沙箱环境密钥
  5. 修改你的 pay.php 文件
    • $aop->appId 和密钥替换成 沙箱环境APPID沙箱密钥
    • 非常重要:沙箱环境的密钥也需要在沙箱环境的“接口加签方式”里生成和配置。
  6. 获取沙箱账号:在沙箱环境页面,你可以找到两个测试账号:一个买家账号(用于扫码支付),一个卖家账号(用于查看收款)。
  7. 访问你的支付页面:用你的网站访问 pay.php?order_id=test123,会跳转到支付宝收银台,你可以使用沙箱买家账号扫码支付,整个过程不会产生真实资金。

第六步:部署到生产环境

测试通过后,即可切换到生产环境。

  1. 关闭沙箱环境
  2. 修改 pay.php 文件
    • $aop->appId 和密钥替换回 生产环境 的真实 APPID 和密钥。
  3. 确保回调地址可被支付宝访问
    • pay_return.phppay_notify.php 必须可以通过公网IP和域名访问。
    • 如果你使用的是本地开发环境,可以使用内网穿透工具(如花生壳、ngrok)将本地端口映射到公网,以便支付宝能回调成功。
    • 在生产服务器上,确保服务器的防火墙和云服务商(如阿里云、腾讯云)的安全组策略放行了80和443端口。
  4. 再次完整测试:使用真实支付宝账号进行一笔小额测试支付,确保一切正常。

总结与注意事项

  • 安全第一:永远不要将你的私钥泄露给任何人。
  • 幂等性:异步回调处理逻辑中,一定要有防止重复处理的机制。
  • 日志记录:无论是支付请求还是回调,都建议记录详细的日志,方便排查问题。
  • 用户体验:同步回调页面应简洁明了,并尽快跳转回用户的会员中心或订单详情页。
  • 错误处理:对可能出现的异常情况(如网络中断、数据库连接失败等)进行捕获和处理。

这份教程涵盖了从申请到部署的全过程,希望能帮助你成功在 Dedecms 中集成支付宝支付功能,如果在操作中遇到具体问题,可以提供错误信息,我会尽力帮你分析。