核心思想
在织梦中使用微信支付,主要有两种方式:

(图片来源网络,侵删)
- 官方推荐的API方式(更稳定、更灵活):这是目前最主流和推荐的方式,你需要向微信支付平台申请成为商户,获取API密钥等凭证,然后在自己的服务器上编写代码来调用微信支付的接口。
- 第三方插件/服务(更简单、快速):市面上有一些开发者制作的织梦微信支付插件,或者使用像“有赞”、“微盟”这样的第三方SaaS服务,这种方式对技术要求低,但可能需要支付费用,并且在定制化和长期维护上不如自建。
本文将重点讲解第一种方式(官方API),因为它最可靠,且能让你真正掌握整个流程。
第一步:准备工作(申请微信支付商户号)
在开始任何代码工作之前,你必须先完成以下准备工作,这是所有后续步骤的基础。
-
注册微信支付商户号:
- 访问 微信支付商户平台。
- 点击“立即注册”,选择“企业账户”或“个体工商户账户”进行注册。个人用户无法申请微信支付功能。
- 按照指引完成企业资质认证、法人信息认证、银行账户验证等流程,这个过程通常需要几天时间,请耐心等待审核通过。
-
获取关键凭证:
(图片来源网络,侵删)- 商户号:审核通过后,在商户平台首页可以找到,通常是一个
mch_id格式的字符串。 - API密钥(API Key / APIv3密钥):这是最重要的凭证,用于签名和验签,确保数据安全。
- 在商户平台,进入【账户中心】->【API安全】->【API密钥(32位)】。
- 设置并妥善保管好你的API密钥,切勿泄露。
- API证书:在【API安全】->【API证书】中,你可以下载你的商户证书和平台证书,在JSAPI支付等场景下需要用到。
- 商户号:审核通过后,在商户平台首页可以找到,通常是一个
-
开通产品并配置:
- 在商户平台,进入【产品中心】。
- 开启你需要的产品,
- JSAPI支付:在网站或H5页面中调起支付,这是最常见的网页支付方式。
- Native支付:生成二维码,用户用微信扫码支付。
- H5支付:在手机浏览器中调起支付。
- 配置支付授权目录:在【产品中心】->【JSAPI支付】或【H5支付】中,设置你的网站域名,如果你的支付页面是
https://www.yourdomain.com/pay.php,那么你就需要将https://www.yourdomain.com添加到授权目录中,否则,用户在微信中打开时会提示“商户未注册此公众号”或“支付请求缺少参数”。
第二步:在织梦网站中实现支付流程
准备工作完成后,我们就可以开始写代码了,整个支付流程通常分为两个部分:前端(用户下单) 和 后端(处理支付和回调)。
流程概览
- 用户下单:用户在织梦网站中选择商品,点击“去支付”。
- 生成订单:网站后端(PHP)根据商品信息,生成一个唯一的订单号(
out_trade_no)。 - 调用统一下单API:后端代码携带订单信息、商户信息、用户信息等,向微信支付服务器发送请求,调用“统一下单”接口。
- 返回预支付ID:微信服务器验证请求后,返回一个预支付交易会话ID(
prepay_id)。 - 前端调起支付:后端将
prepay_id等信息安全地传递给前端,前端使用微信JS-SDK(网页)或WeixinJSBridge(App内嵌浏览器)调起微信支付界面。 - 用户支付:用户在微信中输入密码完成支付。
- 微信异步通知:支付成功后,微信服务器会向你在商户平台配置的回调URL发送一个POST请求,通知你支付结果。
- 处理通知并更新订单:你的网站后端接收通知,验证签名,确认支付成功,然后将织梦系统中的订单状态更新为“已支付”。
- 前端显示结果:用户支付完成后,页面跳转到支付成功或失败页面。
第三步:代码实现详解
假设我们要实现一个JSAPI支付(在网页中调起支付)。
下载微信支付PHP SDK
为了简化开发,强烈建议使用官方或社区维护的PHP SDK,你可以在GitHub上搜索 wechatpay-php-sdk 等关键词。

(图片来源网络,侵删)
- 官方推荐:wechatpay-v3-php (这是v3版本的SDK,推荐使用)
- 社区常用:wechatpay-php (一个流行的v2/v3兼容SDK)
下载后,将SDK的核心文件(如 WechatPay.php)放到你的织梦网站根目录下的一个文件夹,/weixinpay/。
创建支付处理文件(/pay.php)
这个文件将处理后端逻辑。
a. 初始化配置
<?php
require_once '../include/common.inc.php'; // 引入织梦核心文件,方便调用织梦函数
require_once '../weixinpay/vendor/autoload.php'; // 引入Composer自动加载(如果你用Composer安装的SDK)
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Formatter;
// 微信支付配置
$config = [
'mchid' => '你的商户号', // 商户号
'serial' => '你的商户API证书序列号', // 在商户平台API证书页面可以找到
'private_key' => Rsa::from('file://path/to/your/apiclient_key.pem', Rsa::KEY_TYPE_PRIVATE), // 你的商户私钥文件路径
'cert' => Rsa::from('file://path/to/your/apiclient_cert.pem', Rsa::KEY_TYPE_CERT), // 你的商户证书文件路径
'secret_key' => '你的APIv3密钥', // APIv3密钥
];
// 构建一个APIv3实例
$instance = Builder::factory($config);
b. 生成织梦订单
// 假设订单ID是从URL参数获取的,pay.php?orderid=123
$orderid = isset($_GET['orderid']) ? intval($_GET['orderid']) : 0;
if (!$orderid) {
die('订单ID错误');
}
// 获取织梦订单信息
$dsql = new DedeSql(false);
$row = $dsql->GetOne("SELECT * FROM `#@__addonorder` WHERE id = $orderid"); // 假设订单存在这个表里,请根据你的实际表结构调整
if (!$row) {
die('订单不存在');
}
$amount = $row['price'] * 100; // 微信支付金额单位为“分”,需要乘以100
$out_trade_no = $row['dede_orderno']; // 织梦生成的订单号,确保唯一
$subject = $row['title']; // 商品名称
$body = '购买商品:' . $subject; // 商品描述
c. 调用统一下单API
try {
// 调用统一下单API
$result = $instance->chain('v3/pay/transactions/jsapi')->post([
'json' => [
'appid' => '你的公众号AppID', // 公众号的AppID,JSAPI支付必须
'mchid' => $config['mchid'],
'description' => $body,
'out_trade_no' => $out_trade_no,
'notify_url' => 'https://www.yourdomain.com/notify.php', // 异步通知URL,见下一步
'amount' => [
'total' => $amount,
'currency' => 'CNY'
],
'payer' => [
'openid' => '用户的openid' // JSAPI支付必须获取用户的openid
]
],
]);
// 解析返回结果
$prepayId = $result['prepay_id'];
// --- 生成前端调起支付所需的参数 ---
$jsApiParams = $instance->chain('v3/pay/transactions/jsapi')->prepare($result['prepay_id']);
$params = [
'appId' => $jsApiParams['appId'],
'timeStamp' => $jsApiParams['timeStamp'],
'nonceStr' => $jsApiParams['nonceStr'],
'package' => $jsApiParams['package'],
'signType' => $jsApiParams['signType'],
];
$jsonParams = json_encode($params);
} catch (\Exception $e) {
// 统一下单失败,记录错误日志
// 将错误信息写入数据库或文件
// die('下单失败:' . $e->getMessage());
header("Location: /payfail.php?msg=下单失败");
exit;
}
d. 获取用户OpenID
JSAPI支付必须获取用户的 openid,获取方式有几种:
- 用户在微信内置浏览器中访问:通过微信JS-SDK的
wx.login和wx.getUserInfo获取。 - 通过OAuth2.0授权:引导用户点击链接,微信回调后获取
code,再用code换取openid。
这是最复杂的一步,需要前端和后端配合,这里假设你已经通过某种方式获取了 $openid。
创建前端支付页面(/payfor.php)
这个页面显示订单信息,并包含一个“立即支付”按钮。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">确认支付</title>
<!-- 引入微信JS-SDK -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
</head>
<body>
<h1>订单确认</h1>
<p>订单号:<?php echo $row['dede_orderno']; ?></p>
<p>支付金额:<?php echo $row['price']; ?> 元</p>
<button id="payButton">立即支付</button>
<script>
document.getElementById('payButton').onclick = function() {
// 从后端获取支付参数
var payParams = <?php echo $jsonParams; ?>;
// 调起微信支付
if (typeof WeixinJSBridge !== "undefined") {
WeixinJSBridge.invoke('getBrandWCPayRequest', {
"appId": payParams.appId,
"timeStamp": payParams.timeStamp,
"nonceStr": payParams.nonceStr,
"package": payParams.package,
"signType": payParams.signType
}, function(res) {
if (res.err_msg === "get_brand_wcpay_request:ok") {
// 支付成功
alert('支付成功!');
window.location.href = '/paysuccess.php?orderid=<?php echo $orderid; ?>';
} else {
// 支付失败或取消
alert('支付失败或已取消。');
window.location.href = '/payfail.php?orderid=<?php echo $orderid; ?>';
}
});
} else {
// 如果不在微信环境,提示用户
alert('请在微信内打开此页面进行支付。');
}
};
</script>
</body>
</html>
创建异步通知处理文件(/notify.php)
这是最关键的一步,用于处理微信的支付结果通知。
<?php
require_once '../include/common.inc.php';
require_once '../weixinpay/vendor/autoload.php';
// 使用同一个SDK实例
$config = [ ... ]; // 同上
$instance = Builder::factory($config);
// 获取POST数据
$notifyData = file_get_contents('php://input');
// 验证签名并解密通知
try {
$result = $instance->chain('v3/pay/transactions/out-trade-no/{out_trade_no}')->get(['out_trade_no' => $out_trade_no]); // 这个是主动查询,更推荐
// 或者直接验签通知(更被动)
// $result = $instance->verify($notifyData, $instance->getNotifySignature($notifyData));
// 检查交易状态
if ($result['trade_state'] === 'SUCCESS') {
// 1. 验证商户订单号
$outTradeNo = $result['out_trade_no'];
// 2. 查询织梦订单
$dsql = new DedeSql(false);
$row = $dsql->GetOne("SELECT * FROM `#@__addonorder` WHERE dede_orderno = '$outTradeNo'");
if ($row && $row['status'] != 1) { // 假设status=1为已支付
// 3. 验证金额
$totalFee = $result['amount']['total'] / 100; // 转换为元
if (abs($totalFee - $row['price']) < 0.01) {
// 4. 更新订单状态
$dsql->ExecuteNoneQuery("UPDATE `#@__addonorder` SET status = 1, paytime = NOW() WHERE id = {$row['id']}");
// 可以在这里进行其他操作,如发货、发送通知邮件等
// 告诉微信服务器收到通知
echo '<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>';
exit;
}
}
}
} catch (\Exception $e) {
// 验证失败或处理出错
// 记录日志
}
// 告诉微信服务器处理失败
echo '<xml><return_code><![CDATA[FAIL]]></return_code></xml>';
总结与注意事项
- 安全第一:API密钥和私钥是生命线,一定要保管好,不要上传到公共代码仓库。
- 环境隔离:开发时使用微信支付的“测试商户号”和沙箱环境,避免直接用正式环境进行调试。
- 错误处理:代码中必须包含完善的错误处理和日志记录机制,方便排查问题。
- 订单幂等性:在处理异步通知时,务必先查询订单状态,避免重复处理导致业务逻辑错误。
- 域名配置:不要忘记在微信商户平台配置支付授权目录和异步通知URL。
- 选择合适的支付方式:根据你的场景(PC网站、手机网站、App内)选择JSAPI、H5或Native支付。
- 织梦适配:本示例中的织梦数据库表(如
#@__addonorder)和字段(如dede_orderno)是假设的,你需要根据你实际使用的织梦商城或订单模块进行修改。
这个过程比较复杂,如果你对PHP编程不熟悉,可能会感到吃力,在这种情况下,可以考虑聘请一名有经验的PHP开发者来完成集成工作,或者使用成熟的第三方织梦支付插件。
