织梦自定义支付接口如何安全高效集成?

99ANYc3cd6
预计阅读时长 30 分钟
位置: 首页 织梦建站 正文
  1. 前端页面:用户点击支付按钮,发起支付请求。
  2. 后端处理:织梦系统接收到请求,生成订单,并调用你的自定义支付逻辑。
  3. 支付回调:支付平台(如支付宝、微信)处理完支付后,通知你的服务器,更新订单状态。

下面我们以一个模拟的“银行转账”支付接口为例,为你提供一个完整、可操作的步骤指南,你可以基于这个框架,轻松替换成真实的支付宝、微信等接口。

织梦自定义支付接口
(图片来源网络,侵删)

准备工作:核心文件结构

织梦的支付接口通常放在 /include/payment/ 目录下,我们需要创建以下文件:

  • /include/payment/mybank/ (创建一个新文件夹,命名规则为小写)
    • mybank.class.php (核心支付类文件)
    • config.php (配置文件,用于在后台显示设置项)
    • return.php (同步返回页面,用户支付后跳转回的页面)
    • notify.php (异步通知页面,支付服务器主动通知的页面)

第一步:创建支付配置文件 (config.php)

这个文件用于在织梦后台的“支付插件”管理中显示配置项,如商户号、密钥等。

文件路径: /include/payment/mybank/config.php

<?php
if(!defined('DEDEINC')) exit('dedecms');
// 支付接口名称
$cfg['name'] = '模拟银行转账';
// 支付接口简介
$cfg['desc'] = '<font color="red">此为模拟支付接口,仅用于测试!</font>';
// 支付接口版本
$cfg['version'] = '1.0';
// 是否需要生成二维码
$cfg['iscod'] = '0';
// 支付接口作者
$cfg['author'] = 'Your Name';
// 支付接口主页
$cfg['homepage'] = 'https://your-website.com';
// 支付接口需要的配置项,这里会显示在后台
$payment_cfg = array(
    // 商户号
    array('mybank_merchant_id', '商户号', 'text', 'TEST001', '请填写您的银行商户号'),
    // 商户密钥 (用于签名验证)
    array('mybank_key', '商户密钥', 'password', 'test123456', '请填写您的银行商户密钥'),
);
?>

第二步:创建核心支付类文件 (mybank.class.php)

这是整个支付逻辑的核心,负责生成支付表单、处理回调等。

织梦自定义支付接口
(图片来源网络,侵删)

文件路径: /include/payment/mybank/mybank.class.php

<?php
if(!defined('DEDEINC')) exit('dedecms');
require_once(DEDEINC.'/payment.class.php');
// 继承织梦的基类 payment
class mybank extends Payment {
    // 商户号和密钥,从配置中读取
    var $mybank_merchant_id;
    var $mybank_key;
    // 构造函数,初始化配置
    function __construct($ $cfg = array()){
        parent::__construct($ $cfg);
        $this->mybank_merchant_id = $this->getCfg('mybank_merchant_id');
        $this->mybank_key = $this->getCfg('mybank_key');
    }
    // 创建支付表单
    function getCode($ $order, $ $product, $ $money, $ $cardnum, $ $bankid){
        // 1. 生成一个唯一的订单号(如果订单系统没提供的话)
        // $order['ddh'] 是织梦订单系统传过来的订单号
        $order_sn = $order['ddh'];
        // 2. 生成签名 (模拟)
        // 将订单号、金额、商户号按一定规则拼接,并用密钥加密
        $sign_str = $order_sn . $money . $this->mybank_merchant_id;
        $sign = md5($sign_str . $this->mybank_key);
        // 3. 构造要提交到支付网关的参数
        $ $params = array(
            'merchant_id' => $this->mybank_merchant_id,
            'order_sn'    => $order_sn,
            'amount'      => $money,
            'subject'     => $product, // 商品名称
            'body'        => '订单描述',
            'return_url'  => $this->GetNotifyUrl(), // 同步回调地址
            'notify_url'  => $this->GetNotifyUrl(), // 异步回调地址
            'sign'        => $sign,
            'time'        => time(),
        );
        // 4. 生成支付表单HTML
        // 这里我们模拟一个跳转到一个“模拟支付页面”的表单
        $ $sform = '<form id="payform" name="payform" action="https://your-mock-payment-gateway.com/pay" method="post">';
        foreach($ $params as $ $key => $ $val){
            $ $sform .= '<input type="hidden" name="'.$key.'" value="'.$val.'"/>';
        }
        $ $sform .= '<input type="submit" value="确认支付">';
        $ $sform .= '</form>';
        $ $sform .= '<script>document.getElementById("payform").submit();</script>';
        return $ $sform;
    }
    // 处理同步返回 (用户支付后点击“返回商家”或页面自动跳转)
    function receive()
    {
        // 1. 获取返回的参数
        $ $order_sn = isset($ $GLOBALS['order_sn']) ? trim($ $GLOBALS['order_sn']) : '';
        $ $sign = isset($ $GLOBALS['sign']) ? trim($ $GLOBALS['GLOBALS']['sign']) : '';
        // 2. 验证签名 (防止伪造)
        $sign_str = $order_sn . $GLOBALS['amount'] . $this->mybank_merchant_id;
        $my_sign = md5($sign_str . $this->mybank_key);
        if ($my_sign != $sign) {
            die('签名验证失败,数据可能被篡改!');
        }
        // 3. 根据订单号查询订单状态
        // 注意:这里只是模拟,实际应该调用你自己的订单查询API
        // 假设订单总是支付成功
        $this->ConfirmOrder($order_sn, 'Y');
        // 4. 显示支付成功页面,并跳转
        $msg = '<div style="text-align:center; margin-top:50px;">';
        $msg .= '<h2>支付成功!</h2>';
        $msg .= '<p>您的订单号:' . $order_sn . '</p>';
        $msg .= '<p>正在跳转到订单详情页...</p>';
        $msg .= '</div>';
        echo $msg;
        echo '<script>setTimeout(function(){ window.location.href="/member/order_list.php"; }, 3000);</script>';
        exit;
    }
    // 处理异步通知 (支付服务器主动通知)
    function notify()
    {
        // 1. 获取通知参数
        $ $order_sn = isset($ $GLOBALS['order_sn']) ? trim($ $GLOBALS['order_sn']) : '';
        $ $sign = isset($ $GLOBALS['sign']) ? trim($ $GLOBALS['GLOBALS']['sign']) : '';
        $ $trade_status = isset($ $GLOBALS['trade_status']) ? trim($ $GLOBALS['trade_status']) : '';
        // 2. 验证签名 (至关重要!)
        $sign_str = $order_sn . $GLOBALS['amount'] . $this->mybank_merchant_id;
        $my_sign = md5($sign_str . $this->mybank_key);
        if ($my_sign != $sign) {
            // 签名错误,通知支付服务器失败
            echo 'fail';
            exit;
        }
        // 3. 根据交易状态处理订单
        if ($trade_status == 'TRADE_SUCCESS') {
            // 调用基类的确认订单方法,更新订单状态为已支付
            // 这会自动更新织梦订单表和相关状态
            $this->ConfirmOrder($order_sn, 'Y');
            // 通知支付服务器成功
            echo 'success';
        } else {
            // 支付失败
            echo 'fail';
        }
        exit;
    }
    // 查询订单状态 (可选)
    function query()
    {
        // 实现订单状态查询逻辑
        // 返回 'Y' (成功), 'N' (失败), 'P' (处理中)
        return 'Y';
    }
}
?>

第三步:创建同步和异步回调文件

这两个文件是固定的入口点,织梦会自动调用。

文件路径: /include/payment/mybank/return.php

<?php
require_once('../../../include/payment/mybank/mybank.class.php');
$ $pay = new mybank();
$pay->receive();
?>

文件路径: /include/payment/mybank/notify.php

织梦自定义支付接口
(图片来源网络,侵删)
<?php
require_once('../../../include/payment/mybank/mybank.class.php');
$ $pay = new mybank();
$pay->notify();
?>

注意: notify.php 文件的安全性非常重要,确保它不能被直接访问,除了你的支付服务器,在生产环境中,可以添加IP白名单验证。


第四步:在织梦后台启用支付接口

  1. 登录织梦后台。
  2. 进入 【系统】->【系统基本参数】->【支付插件】
  3. 在列表中找到你刚刚创建的 “模拟银行转账” 接口。
  4. 点击 “启用”
  5. (重要)“支付网关地址” 中填入你的 notify.php 文件的完整URL
    • https://www.your-website.com/include/payment/mybank/notify.php
    • 这个地址需要能被公网访问,支付服务器会向这个地址发送通知。

第五步:修改订单提交页面(可选)

默认情况下,织梦的订单提交页面会调用 getCode 方法,但如果你想自定义支付流程(比如先跳转到你的支付页面,再让用户去银行转账),你可以修改 member/buy_action.php 文件中的相关逻辑,直接输出你自定义的HTML或跳转链接,而不是调用 $pay->getCode()


真实支付接口(如支付宝/微信)开发要点

将上述模拟接口替换为真实接口,核心思路不变,但具体实现细节有差异:

  1. 获取官方SDK:去支付宝/微信开放平台下载官方的PHP SDK,并放到你的项目中。
  2. 配置文件 (config.php)
    • 支付宝:需要配置 APPID, 应用私钥, 支付宝公钥
    • 微信:需要配置 APPID, 商户号, API密钥
  3. 核心类 (mybank.class.php)
    • 引入SDK:在类文件顶部 require_once 引入SDK的核心文件。
    • 构造函数:从配置中读取APPID、密钥等。
    • getCode() 方法
      • 使用SDK的类(如 AlipayTradePagePayRequest)来构建请求参数。
      • 调用SDK的 sdkExecute() 方法,生成支付宝的表单HTML或微信的跳转URL。
      • 返回给前端的是一个完整的、提交到支付宝/微信服务器的 <form> 表单。
    • notify() 方法
      • 使用SDK的 checkV1() 或类似方法来验证异步通知的签名。
      • 验证通过后,再调用 $this->ConfirmOrder() 更新订单状态。
      • 必须向微信/支付宝服务器返回 successfail 字符串,否则会重复通知。
  4. 回调文件 (return.php, notify.php)

    逻辑基本不变,它们是调用核心类方法的入口。

开发织梦自定义支付接口的关键在于:

  • 遵循规范:文件名、类名、方法名要符合织梦的约定。
  • 利用基类:继承 payment 类,利用它提供的方法(如 ConfirmOrder)来安全地更新订单状态。
  • 安全第一:特别是异步通知 notify.php必须做签名验证,防止伪造支付成功。
  • 区分同步与异步:同步是用户体验,异步是业务核心,务必处理好异步通知。

希望这个详细的指南能帮助你成功开发出自定义支付接口!

-- 展开阅读全文 --
头像
dede首页评论数如何调用或显示?
« 上一篇 昨天
单片机跑马灯C语言程序如何实现?
下一篇 » 昨天

相关文章

取消
微信二维码
支付宝二维码

目录[+]