乐于分享
好东西不私藏

UniApp 小程序支付流程完整对接——前端零坑版

UniApp 小程序支付流程完整对接——前端零坑版

UniApp 小程序支付流程完整对接——前端零坑版

阅读时长:约 15 分钟 | 代码可直接复制使用 | 覆盖 90% 常见报错


一、支付流程概述

1.1 完整时序图

┌─────────┐     ┌─────────┐     ┌─────────┐     ┌────────┐     ┌─────────┐│  用户   │     │  前端   │     │  后端   │     │ 微信   │     │ 商户后台││         │     │(UniApp) │     │(Node.js)│     │ 支付   │     │         │└────┬────┘     └────┬────┘     └────┬────┘     └────┬───┘     └────┬────┘     │               │              │              │              │     │  1.点击支付    │              │              │              │     │───────────────>              │              │              │     │               │              │              │              │     │               │  2.创建订单   │              │              │     │               │───────────────>              │              │     │               │              │              │              │     │               │              │  3.统一下单   │              │     │               │              │──────────────>              │     │               │              │              │              │     │               │              │  4.返回prepay_id             │     │               │              │<──────────────              │     │               │              │              │              │     │               │  5.返回签名参数               │              │     │               │<───────────────              │              │     │               │              │              │              │     │  6.调起支付   │              │              │              │     │<───────────────              │              │              │     │               │              │              │              │     │  7.输入密码   │              │              │              │     │───────────────>              │              │              │     │               │              │              │              │     │               │              │  8.异步回调通知              │     │               │              │<───────────────              │     │               │              │              │              │     │               │              │  9.更新订单状态              │     │               │              │─────────────────────────────>│     │               │              │              │              │     │  10.支付结果页│              │              │              │     │<───────────────              │              │              │

1.2 一句话总结

前端只负责调起支付,核心逻辑在后端。 微信支付的订单创建、签名、回调验证全部在后端完成,前端拿到参数后调用 uni.requestPayment 即可。

1.3 三种支付方式的区别

类型
调起方式
场景
小程序支付uni.requestPayment
 (provider: ‘wxpay’)
微信小程序内支付
APP 支付
微信开放平台 SDK
iOS/Android 原生应用
H5 支付
微信内调起
微信外 H5 页面(不推荐)

本文专注小程序支付。


二、前置准备(UniApp 小程序端)

2.1 材料清单

材料
获取位置
备注
微信小程序 AppID
微信公众平台
格式:wx 开头的 18 位字符串
微信商户号 mch_id
微信商户平台
格式:10 位数字
APIv2 / APIv3 密钥
商户平台 → API 安全
v2 用 MD5 签名,v3 用 RSA
SSL 证书
自备或云服务申请
HTTPS 域名必须
支付域名
商户平台 → 支付配置
格式:https://yourdomain.com

2.2 UniApp 配置

manifest.json 中补充微信小程序配置:

{  "mp-weixin": {    "appid": "wx1234567890abcdef",  // 你的小程序 AppID    "requireSubscribe": false,    "setting": {      "urlCheck": false  // 调试时可关闭,生产环境建议开启    }  }}

2.3 微信开发者工具配置

  1. 打开微信开发者工具

  2. 导入 UniApp 项目(dist/build/mp-weixin 目录)

  3. 工具 → 项目详情 → 支付功能 → 勾选开通

  4. 确保项目域名在白名单内

2.4 HTTPS 域名配置(必读)

⚠️ 微信小程序要求所有接口必须是 HTTPS⚠️ 域名必须备案(国内服务器)⚠️ 证书链必须完整

三、后端统一下单(Node.js 示例)

3.1 安装依赖

npm install axios crypto xml2js

3.2 统一下单接口完整代码

// server/pay.jsconst express = require('express');const axios = require('axios');const crypto = require('crypto');const xml2js = require('xml2js');const router = express.Router();// ==================== 配置区 ====================const WX_CONFIG = {  appid: 'wx1234567890abcdef',       // 小程序 appid  mch_id: '1234567890',              // 商户号  api_key: 'your_api_key_here',      // APIv2 密钥(32位)  notify_url: 'https://yourdomain.com/api/pay/notify', // 回调地址};// ==================== 工具函数 ====================/** * 生成随机字符串 */function generateNonceStr(length = 32) {  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';  let str = '';  for (let i = 0; i < length; i++) {    str += chars.charAt(Math.floor(Math.random() * chars.length));  }  return str;}/** * 生成订单号(可自定义格式) */function generateOutTradeNo() {  return `ORDER${Date.now()}${Math.random().toString(36).substr(2, 9)}`;}/** * 计算 MD5 签名(APIv2) */function makeSign(obj, key) {  // 1. 排序并拼接 key=value 形式  const sortedKeys = Object.keys(obj).sort();  const signStr = sortedKeys    .filter(k => obj[k] !== '' && obj[k] !== undefined && obj[k] !== null)    .map(k => `${k}=${obj[k]}`)    .join('&');  // 2. 拼接 API 密钥  const signStrWithKey = `${signStr}&key=${key}`;  // 3. MD5 加密转大写  return crypto    .createHash('md5')    .update(signStrWithKey, 'utf8')    .digest('hex')    .toUpperCase();}/** * 转换对象为 XML */function objectToXml(obj) {  let xml = '<xml>';  for (const [key, value] of Object.entries(obj)) {    xml += `<${key}><![CDATA[${value}]]></${key}>`;  }  xml += '</xml>';  return xml;}/** * 解析 XML 为对象 */async function xmlToObject(xml) {  return xml2js.parseStringPromise(xml, { explicitArray: false });}// ==================== 统一下单接口 ====================/** * POST /api/pay/create * 创建支付订单 */router.post('/create', async (req, res) => {  try {    const { orderId, totalFee, body = '小程序支付订单' } = req.body;    // 1. 参数校验    if (!orderId || !totalFee) {      return res.json({ code: 400, msg: '缺少必要参数' });    }    // 2. 构造统一下单参数    const outTradeNo = generateOutTradeNo();    const nonceStr = generateNonceStr();    const timeStamp = Math.floor(Date.now() / 1000).toString();    const unifiedOrderParams = {      appid: WX_CONFIG.appid,      mch_id: WX_CONFIG.mch_id,      nonce_str: nonceStr,      body: body,                    // 商品描述      out_trade_no: outTradeNo,      // 商户订单号      total_fee: Math.round(totalFee * 100), // 金额,单位分(必须整数!)      spbill_create_ip: req.ip,      // 发起支付 IP      notify_url: WX_CONFIG.notify_url,      trade_type: 'JSAPI',           // 小程序固定值      openid: req.body.openid,       // 用户 openid(必须)    };    // 3. 计算签名    const sign = makeSign(unifiedOrderParams, WX_CONFIG.api_key);    unifiedOrderParams.sign = sign;    // 4. 发送请求到微信支付    const xmlData = objectToXml(unifiedOrderParams);    const wxResponse = await axios.post(      'https://api.mch.weixin.qq.com/pay/unifiedorder',      xmlData,      {        headers: { 'Content-Type': 'text/xml' },        timeout: 10000,      }    );    // 5. 解析微信返回结果    const result = await xmlToObject(wxResponse.data);    const { return_code, return_msg, result_code, prepay_id, err_code, err_msg } = result.xml;    if (return_code === 'FAIL') {      return res.json({ code: 500, msg: return_msg });    }    if (result_code === 'FAIL') {      return res.json({ code: 500, msg: err_msg || '统一下单失败' });    }    // 6. 前端调起支付所需的签名参数(再次签名)    const paySignParams = {      appId: WX_CONFIG.appid,      timeStamp: timeStamp,      nonceStr: nonceStr,      package: `prepay_id=${prepay_id}`,  // ⚠️ 必须包含 prepay_id= 前缀      signType: 'MD5',    };    const paySign = makeSign(paySignParams, WX_CONFIG.api_key);    // 7. 返回给前端    res.json({      code: 200,      msg: 'success',      data: {        orderId: outTradeNo,        // 商户订单号        timeStamp: timeStamp,       // 时间戳        nonceStr: nonceStr,         // 随机字符串        package: paySignParams.package, // prepay_id=xxx        signType: 'MD5',            // 签名类型        paySign: paySign,           // 支付签名        // 保存 prepay_id 用于后续查单        prepayId: prepay_id,      },    });  } catch (error) {    console.error('统一下单失败:', error);    res.json({ code: 500, msg: '服务器错误' });  }});module.exports = router;

3.3 参数说明表

参数
说明
注意事项
appid
小程序 ID
必须与调起支付的小程序一致
mch_id
商户号
微信商户平台获取
nonce_str
随机字符串
32 位以内,防重放攻击
body
商品描述
必填,最多 128 字符
out_trade_no
商户订单号
自己生成,保证唯一
total_fee
金额(分)
必须是整数
,乘以 100
spbill_create_ip
终端 IP
用户真实 IP,不能是 127.0.0.1
notify_url
回调地址
必须是 HTTPS,外网可访问
trade_type
交易类型
小程序固定 JSAPI
openid
用户标识
通过微信登录获取

四、前端调起支付(UniApp 原生写法)

4.1 获取用户 openid

// utils/auth.js/** * 获取微信登录凭证 code */function getWxCode() {  return new Promise((resolve, reject) => {    // #ifdef MP-WEIXIN    uni.login({      provider: 'weixin',      success: (res) => {        if (res.code) {          resolve(res.code);        } else {          reject(new Error('获取 code 失败'));        }      },      fail: reject,    });    // #endif    // #ifndef MP-WEIXIN    reject(new Error('仅支持微信小程序'));    // #endif  });}/** * 通过 code 获取 openid */async function getOpenid(code) {  const res = await uni.request({    url: 'https://yourdomain.com/api/auth/openid',    method: 'POST',    data: { code },  });  return res.data.data.openid;}

4.2 支付页面完整代码

<!-- pages/pay/pay.vue --><template>  <view class="container">    <view class="order-info">      <text class="title">订单金额</text>      <text class="price">¥{{ orderInfo.price }}</text>    </view>    <button       class="pay-btn"       :disabled="isPaying"      @click="handlePay"    >      {{ isPaying ? '支付中...' : '微信支付' }}    </button>  </view></template><script>// #ifdef MP-WEIXINexport default {  data() {    return {      orderId: '',      orderInfo: {        price: 0.01,        goods: '测试商品',      },      isPaying: false,     // 防止重复点击      payLock: false,      // 支付锁    };  },  onLoad(options) {    this.orderId = options.orderId || '';    // 实际项目中这里应该调接口获取订单详情  },  methods: {    /**     * 支付按钮点击事件     */    async handlePay() {      // 🔒 防重处理:避免用户多次点击      if (this.payLock) {        uni.showToast({ title: '支付进行中,请稍候', icon: 'none' });        return;      }      this.payLock = true;      this.isPaying = true;      try {        // ========== 步骤1:获取 openid ==========        const openid = await this.getUserOpenid();        // ========== 步骤2:调用后端创建订单 ==========        const orderRes = await uni.request({          url: 'https://yourdomain.com/api/order/create',          method: 'POST',          data: {            goodsId: this.orderId,            totalFee: this.orderInfo.price,            openid: openid,          },        });        if (orderRes.data.code !== 200) {          throw new Error(orderRes.data.msg || '创建订单失败');        }        const payData = orderRes.data.data;        // ========== 步骤3:调起微信支付 ==========        await this.requestPayment(payData);        // ========== 步骤4:支付成功后的处理 ==========        uni.showToast({ title: '支付成功', icon: 'success' });        // 跳转到订单页或支付成功页        setTimeout(() => {          uni.navigateTo({            url: '/pages/order/success?orderId=' + payData.orderId,          });        }, 1500);      } catch (err) {        this.handlePayError(err);      } finally {        // 释放锁        this.payLock = false;        this.isPaying = false;      }    },    /**     * 获取用户 openid     */    getUserOpenid() {      return new Promise((resolve, reject) => {        // 方式1:前端直接获取 code 传给后端        uni.login({          provider: 'weixin',          success: (res) => {            if (!res.code) {              reject(new Error('获取 code 失败'));              return;            }            // 调用后端接口获取 openid            uni.request({              url: 'https://yourdomain.com/api/auth/openid',              method: 'POST',              data: { code: res.code },              success: (r) => {                if (r.data.code === 200) {                  resolve(r.data.data.openid);                } else {                  reject(new Error('获取 openid 失败'));                }              },              fail: reject,            });          },          fail: reject,        });      });    },    /**     * 调起微信支付     */    requestPayment(payData) {      return new Promise((resolve, reject) => {        uni.requestPayment({          provider: 'wxpay',       // 微信支付          timeStamp: payData.timeStamp,  // 时间戳(字符串)          nonceStr: payData.nonceStr,     // 随机字符串          package: payData.package,       // ⚠️ 格式:prepay_id=xxx          signType: payData.signType,     // 签名类型:MD5 / HMAC-SHA256          paySign: payData.paySign,       // 签名          success: (res) => {            console.log('✅ 支付成功', res);            resolve(res);          },          fail: (err) => {            console.log('❌ 支付失败', err);            reject(err);          },        });      });    },    /**     * 处理支付错误     */    handlePayError(err) {      console.error('支付异常:', err);      const errMsg = err.errMsg || '';      // 用户取消支付      if (errMsg.includes('cancel') || errMsg.includes('取消')) {        uni.showToast({ title: '用户取消支付', icon: 'none' });        return;      }      // 常见错误提示优化      const errorMap = {        '2': '支付失败',        '-1': '支付失败',        'SYSTEM_ERROR': '系统错误,请重试',        'BANKERROR': '银行错误,请联系客服',        'USERPAYING': '支付中,请稍后查看',      };      const msg = errorMap[err.errCode] || err.message || '支付失败';      uni.showToast({ title: msg, icon: 'none' });      // 💡 建议:这里可以做一次查单,确保订单状态      this.queryOrderStatus();    },    /**     * 查询订单状态(防止掉单)     */    async queryOrderStatus() {      if (!this.orderId) return;      try {        const res = await uni.request({          url: 'https://yourdomain.com/api/order/query',          method: 'POST',          data: { orderId: this.orderId },        });        if (res.data.data.status === 'paid') {          uni.showToast({ title: '订单已支付', icon: 'success' });        }      } catch (e) {        console.error('查单失败', e);      }    },  },};// #endif</script><style scoped>.container {  padding: 40rpx;}.order-info {  background: #fff;  padding: 40rpx;  border-radius: 16rpx;  text-align: center;  margin-bottom: 60rpx;}.title {  display: block;  color: #999;  font-size: 28rpx;  margin-bottom: 20rpx;}.price {  font-size: 60rpx;  font-weight: bold;  color: #333;}.pay-btn {  width: 100%;  height: 96rpx;  line-height: 96rpx;  background: linear-gradient(135deg, #07c160#06ad56);  color: #fff;  font-size: 32rpx;  border-radius: 48rpx;  border: none;}.pay-btn[disabled] {  background: #ccc;}</style>

4.3 注意事项

⚠️ 1. timeStamp 必须是字符串类型,不能是数字⚠️ 2. package 参数格式必须是 prepay_id=xxx(前缀不能省)⚠️ 3. signType 必须与后端签名一致(MD5 / HMAC-SHA256)⚠️ 4. 支付前一定要做防重处理,避免重复扣款⚠️ 5. 使用条件编译 #ifdef MP-WEIXIN 区分平台

五、支付结果通知(后端处理)

5.1 回调接口完整代码

// server/notify.jsconst express = require('express');const crypto = require('crypto');const xml2js = require('xml2js');const router = express.Router();const WX_CONFIG = {  appid: 'wx1234567890abcdef',  mch_id: '1234567890',  api_key: 'your_api_key_here',};/** * 验证微信签名 */function verifySign(params, key) {  const { sign, ...rest } = params;  // 重新计算签名  const sortedKeys = Object.keys(rest).sort();  const signStr = sortedKeys    .filter(k => rest[k] !== '' && rest[k] !== undefined)    .map(k => `${k}=${rest[k]}`)    .join('&');  const signStrWithKey = `${signStr}&key=${key}`;  const calculatedSign = crypto    .createHash('md5')    .update(signStrWithKey, 'utf8')    .digest('hex')    .toUpperCase();  return calculatedSign === sign;}/** * 处理微信支付回调 */router.post('/notify', async (req, res) => {  try {    // 1. 获取原始 XML 数据    const xmlData = req.body.toString('utf8');    console.log('收到微信回调:', xmlData);    // 2. 解析 XML    const parser = new xml2js.Parser({ explicitArray: false });    const result = await parser.parseStringPromise(xmlData);    const data = result.xml;    // 3. 验证签名    if (!verifySign(data, WX_CONFIG.api_key)) {      console.error('签名验证失败');      return res.send(xmlData({ return_code: 'FAIL', return_msg: '签名失败' }));    }    // 4. 处理返回状态    if (data.return_code === 'FAIL') {      console.error('微信返回失败:', data.return_msg);      return res.send(xmlData({ return_code: 'FAIL', return_msg: 'FAIL' }));    }    // 5. 业务逻辑处理    const { out_trade_no, transaction_id, total_fee, cash_fee, trade_state } = data;    // 查询本地订单    const order = await OrderModel.findOne({ orderId: out_trade_no });    if (!order) {      console.error('订单不存在:', out_trade_no);      return res.send(xmlData({ return_code: 'FAIL', return_msg: '订单不存在' }));    }    // 防止重复处理(幂等性)    if (order.status === 'paid') {      console.log('订单已处理过:', out_trade_no);      return res.send(xmlData({ return_code: 'SUCCESS', return_msg: 'OK' }));    }    // 更新订单状态    await OrderModel.updateOne(      { orderId: out_trade_no },      {        status: 'paid',        transactionId: transaction_id,     // 微信订单号        paidAmount: parseInt(total_fee) / 100, // 转换回元        paidAt: new Date(),        notifyData: data,                   // 保存原始回调数据      }    );    // 6. 处理自定义业务(如:发送通知、发放优惠券等)    await handleOrderSuccess(order);    console.log('✅ 订单处理成功:', out_trade_no);    // 7. 返回 SUCCESS 给微信    res.send(xmlData({ return_code: 'SUCCESS', return_msg: 'OK' }));  } catch (error) {    console.error('回调处理异常:', error);    res.send(xmlData({ return_code: 'FAIL', return_msg: 'ERROR' }));  }});/** * 发送 XML 响应 */function xmlData(data) {  let xml = '<xml>';  for (const [key, value] of Object.entries(data)) {    xml += `<${key}><![CDATA[${value}]]></${key}>`;  }  xml += '</xml>';  return xml;}/** * 订单成功后的自定义业务处理 */async function handleOrderSuccess(order) {  // 1. 发送订阅消息通知用户  // 2. 发放积分/优惠券  // 3. 库存扣减  // 4. 触发其他业务系统}module.exports = router;

5.2 回调验证要点

⚠️  1. 必须返回 XML 格式:<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>⚠️  2. 必须验证签名,防止伪造回调⚠️  3. 订单状态更新要做幂等处理(多次回调只处理一次)⚠️  4. 回调地址必须 HTTPS 且外网可访问⚠️  5. 处理完成后立即返回 SUCCESS,不要有延迟操作⚠️  6. 建议记录完整日志,方便排查问题

六、查单接口(防止掉单)

6.1 为什么会掉单?

用户支付成功    ↓微信返回成功(前端看到)    ↓异步回调失败(网络问题 / 服务重启)    ↓订单状态未更新(掉单!)    ↓用户看到支付成功,但订单显示未付款

6.2 后端查单接口

// server/query.jsrouter.post('/query', async (req, res) => {  try {    const { orderId } = req.body;    // 1. 先查本地订单    const localOrder = await OrderModel.findOne({ orderId });    if (!localOrder) {      return res.json({ code: 404, msg: '订单不存在' });    }    // 2. 如果本地已是支付成功,直接返回    if (localOrder.status === 'paid') {      return res.json({        code: 200,        msg: 'success',        data: { status: 'paid', orderInfo: localOrder },      });    }    // 3. 本地未支付,查询微信    const nonceStr = generateNonceStr();    const params = {      appid: WX_CONFIG.appid,      mch_id: WX_CONFIG.mch_id,      out_trade_no: orderId,      nonce_str: nonceStr,    };    params.sign = makeSign(params, WX_CONFIG.api_key);    const xmlData = objectToXml(params);    const wxResponse = await axios.post(      'https://api.mch.weixin.qq.com/pay/orderquery',      xmlData,      { headers: { 'Content-Type': 'text/xml' } }    );    const result = await xmlToObject(wxResponse.data);    const { trade_state, transaction_id, total_fee, time_end } = result.xml;    // 4. 微信已支付,更新本地订单    if (trade_state === 'SUCCESS') {      await OrderModel.updateOne(        { orderId },        {          status: 'paid',          transactionId: transaction_id,          paidAt: new Date(time_end.replace(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/, '$1-$2-$3 $4:$5:$6')),        }      );      return res.json({        code: 200,        msg: 'success',        data: { status: 'paid', orderInfo: await OrderModel.findOne({ orderId }) },      });    }    // 5. 微信也未支付,返回当前状态    res.json({      code: 200,      msg: 'success',      data: { status: trade_state, orderInfo: localOrder },    });  } catch (error) {    console.error('查单失败:', error);    res.json({ code: 500, msg: '查单失败' });  }});

6.3 前端查单策略

// 前端查单最佳实践/** * 支付后轮询查单(兜底方案) */async function pollOrderStatus(orderId, maxAttempts = 5) {  for (let i = 0; i < maxAttempts; i++) {    await new Promise(r => setTimeout(r, 2000)); // 每 2 秒查一次    try {      const res = await uni.request({        url: 'https://yourdomain.com/api/order/query',        method: 'POST',        data: { orderId },      });      if (res.data.data.status === 'paid') {        console.log('订单已支付');        return true;      }    } catch (e) {      console.error('查单失败', e);    }  }  return false;}/** * 支付成功但状态未更新时的兜底处理 */async function handlePaymentSuccess(orderId) {  const updated = await pollOrderStatus(orderId);  if (updated) {    // 跳转成功页    uni.navigateTo({ url: `/pages/order/success?orderId=${orderId}` });  } else {    // 最多等待 10 秒后仍无结果,提示用户稍后查看    uni.showModal({      title: '提示',      content: '支付成功,订单可能存在延迟,请稍后在"我的订单"中查看',      showCancel: false,    });  }}

七、常见问题与避坑(重点!)

7.1 问题排查表

报错信息
可能原因
解决方案
签名错误
前端/后端签名不一致
1. 检查 timeStamp 是否字符串
2. 检查 package 格式是否为 prepay_id=xxx
3. 确认 signType 与后端一致
appid 和 mch_id 不匹配
商户号未绑定小程序
登录商户平台 → 产品中心 → JSAPI支付 → appid配置
或 关联小程序
prepay_id 为空
统一下单失败
1. 检查 body(商品描述)是否为空
2. 检查 total_fee 是否为整数分
3. 检查 openid 是否正确
订单已支付
重复点击 / 回调延迟
1. 前端加支付锁
2. 后端订单状态判断
3. 前端支付后主动查单
支付成功但订单未更新
回调未收到或验证失败
1. 检查 notify_url 是否可访问
2. 检查签名验证逻辑
3. 使用查单接口兜底
沙箱环境报错
沙箱 key 和正式 key 混用
确认当前使用的 API 密钥
沙箱环境需单独申请沙箱密钥
URL 未注册
支付目录未配置
商户平台 → 支付配置 → JSAPI支付
添加授权支付目录
调用JSAPI缺少参数
openid 获取失败
确认用户已登录且已获取 openid
检查 code 是否有效

7.2 避坑指南

坑 1:金额精度问题

// ❌ 错误:浮点数运算可能导致金额错误const total_fee = 0.1 * 100; // 可能是 10.000000000000004// ✅ 正确:使用整数运算(分)const total_fee = 1; // 直接用整数// ✅ 正确:金额转分const price = 0.01;const total_fee = Math.round(price * 100);

坑 2:签名参数名大小写

// ❌ 错误:参数名拼写错误{ time_stamp: '123', package: 'prepay_id=xxx' }// ✅ 正确:严格按照微信文档{ timeStamp: '123', package: 'prepay_id=xxx' }

坑 3:package 前缀丢失

// ❌ 错误:直接传 prepay_idpackage: 'wx1234567890'// ✅ 正确:必须带前缀package: `prepay_id=${prepay_id}`

坑 4:回调未返回 SUCCESS

// ❌ 错误:处理完业务逻辑后才返回await processOrder();  // 这里可能失败res.send(successXml);  // 如果上面失败,永远不会返回 SUCCESS// ✅ 正确:先返回 SUCCESS,再处理业务res.send(successXml);  // 立即返回await processOrder();  // 异步处理其他业务

坑 5:未处理用户取消

// ❌ 错误:未区分取消和其他错误fail: (err) => {  uni.showToast({ title: '支付失败', icon: 'none' });}// ✅ 正确:区分取消和其他错误fail: (err) => {  if (err.errMsg.includes('cancel')) {    // 用户主动取消,不做提示或轻提示    console.log('用户取消支付');  } else {    uni.showToast({ title: '支付失败', icon: 'none' });  }}

7.3 调试技巧

// 1. 前端打印完整支付参数console.log('支付参数:', payData);// 2. 后端打印签名过程console.log('签名原文:', signStrWithKey);console.log('计算签名:', calculatedSign);console.log('微信签名:', sign);// 3. 使用微信支付签名校验工具验证// https://pay.weixin.qq.com/wiki/doc/apiv3/tools/signtool.shtml// 4. 沙箱环境调试// 开通沙箱:商户平台 → 开发者工具 → 沙箱环境// 获取沙箱密钥后替换 api_key

八、快速复制模板

8.1 完整下单页面(UniApp Vue3 + setup)

<!-- pages/pay/pay.vue --><template>  <view class="pay-page">    <view class="goods-card">      <image class="goods-img" src="/static/goods.png" mode="aspectFill" />      <view class="goods-info">        <text class="goods-name">{{ goodsInfo.name }}</text>        <text class="goods-price">¥{{ goodsInfo.price }}</text>      </view>    </view>    <button       class="pay-btn"       :loading="loading"      @click="onPay"    >      微信支付 ¥{{ goodsInfo.price }}    </button>  </view></template><script setup>// #ifdef MP-WEIXINimport { ref, onMounted } from 'vue';const goodsInfo = ref({ id: '001', name: '测试商品', price: '0.01' });const loading = ref(false);const payLock = ref(false);onMounted(() => {  // 获取页面参数  const pages = getCurrentPages();  const currentPage = pages[pages.length - 1];  const options = currentPage.options || {};  if (options.goodsId) {    goodsInfo.value.id = options.goodsId;  }});async function onPay() {  // 防重  if (payLock.value || loading.value) return;  payLock.value = true;  loading.value = true;  try {    // 1. 获取 openid    const openid = await getOpenid();    // 2. 创建订单获取支付参数    const { data: res } = await uni.request({      url: 'https://yourdomain.com/api/order/create',      method: 'POST',      data: {        goodsId: goodsInfo.value.id,        price: goodsInfo.value.price,        openid,      },    });    if (res.code !== 200) {      throw new Error(res.msg);    }    // 3. 调起支付    await uni.requestPayment({      provider: 'wxpay',      ...res.data,    });    // 4. 支付成功    uni.showToast({ title: '支付成功', icon: 'success' });    setTimeout(() => uni.navigateBack(), 1500);  } catch (err) {    const msg = err.errMsg?.includes('cancel') ? '已取消支付' : (err.message || '支付失败');    uni.showToast({ title: msg, icon: 'none' });  } finally {    payLock.value = false;    loading.value = false;  }}function getOpenid() {  return new Promise((resolve, reject) => {    uni.login({      provider: 'weixin',      success: async (loginRes) => {        try {          const { data } = await uni.request({            url: 'https://yourdomain.com/api/auth/openid',            method: 'POST',            data: { code: loginRes.code },          });          resolve(data.data.openid);        } catch (e) {          reject(e);        }      },      fail: reject,    });  });}// #endif</script><style>.pay-page { padding: 40rpx; }.goods-card {   display: flex;   background: #fff  padding: 30rpx;   border-radius: 16rpx;  margin-bottom: 60rpx;}.goods-img { width: 160rpx; height: 160rpx; border-radius: 12rpx; }.goods-info { margin-left: 30rpx; display: flex; flex-direction: column; justify-content: space-between; }.goods-name { font-size: 32rpx; color: #333; }.goods-price { font-size: 40rpx; color: #f60; font-weight: bold; }.pay-btn {   width: 100%;   height: 96rpx;   line-height: 96rpx;   background: #07c160  color: #fff  font-size: 32rpx;  border-radius: 48rpx;}</style>

8.2 完整后端订单接口

// server/routes/order.jsconst express = require('express');const router = express.Router();const axios = require('axios');const crypto = require('crypto');const xml2js = require('xml2js');const WX_CONFIG = {  appid: process.env.WX_APPID,  mch_id: process.env.WX_MCH_ID,  api_key: process.env.WX_API_KEY,  notify_url: process.env.WX_NOTIFY_URL,};// ==================== 工具函数 ====================const genNonceStr = (len = 32) => {  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';  return Array.from({ length: len }, () => chars[Math.floor(Math.random() * chars.length)]).join('');};const makeSign = (obj, key) => {  const str = Object.keys(obj).sort()    .filter(k => obj[k] !== undefined && obj[k] !== '')    .map(k => `${k}=${obj[k]}`)    .join('&') + `&key=${key}`;  return crypto.createHash('md5').update(str, 'utf8').digest('hex').toUpperCase();};const toXml = (obj) => {  let xml = '<xml>';  for (const [k, v] of Object.entries(obj)) {    xml += `<${k}><![CDATA[${v}]]></${k}>`;  }  return xml + '</xml>';};const fromXml = async (xml) => {  return (await xml2js.parseStringPromise(xml, { explicitArray: false })).xml;};// ==================== 创建订单 ====================router.post('/create', async (req, res) => {  try {    const { goodsId, price, openid, body = '小程序支付' } = req.body;    if (!goodsId || !price || !openid) {      return res.json({ code: 400, msg: '参数缺失' });    }    const outTradeNo = `ORDER${Date.now()}${genNonceStr(6)}`;    const nonceStr = genNonceStr();    const timeStamp = Math.floor(Date.now() / 1000).toString();    // 统一下单    const orderParams = {      appid: WX_CONFIG.appid,      mch_id: WX_CONFIG.mch_id,      nonce_str: nonceStr,      body,      out_trade_no: outTradeNo,      total_fee: Math.round(parseFloat(price) * 100), // 金额转分      spbill_create_ip: req.ip,      notify_url: WX_CONFIG.notify_url,      trade_type: 'JSAPI',      openid,    };    orderParams.sign = makeSign(orderParams, WX_CONFIG.api_key);    // 保存订单到数据库(示例)    await saveLocalOrder({ outTradeNo, goodsId, price, status: 'pending' });    // 请求微信    const wxRes = await axios.post(      'https://api.mch.weixin.qq.com/pay/unifiedorder',      toXml(orderParams),      { headers: { 'Content-Type': 'text/xml' } }    );    const wxData = await fromXml(wxRes.data);    if (wxData.return_code !== 'SUCCESS' || wxData.result_code !== 'SUCCESS') {      return res.json({ code: 500, msg: wxData.return_msg || wxData.err_msg });    }    // 二次签名(返回给前端)    const paySignParams = {      appId: WX_CONFIG.appid,      timeStamp,      nonceStr,      package: `prepay_id=${wxData.prepay_id}`,      signType: 'MD5',    };    res.json({      code: 200,      msg: 'success',      data: {        orderId: outTradeNo,        timeStamp,        nonceStr,        package: paySignParams.package,        signType: 'MD5',        paySign: makeSign(paySignParams, WX_CONFIG.api_key),      },    });  } catch (err) {    console.error('创建订单失败', err);    res.json({ code: 500, msg: '服务器错误' });  }});// ==================== 订单查询 ====================router.post('/query', async (req, res) => {  try {    const { orderId } = req.body;    // 查本地    const localOrder = await getLocalOrder(orderId);    if (!localOrder) return res.json({ code: 404, msg: '订单不存在' });    if (localOrder.status === 'paid') {      return res.json({ code: 200, msg: 'success', data: { status: 'paid' } });    }    // 查微信    const nonceStr = genNonceStr();    const params = {      appid: WX_CONFIG.appid,      mch_id: WX_CONFIG.mch_id,      out_trade_no: orderId,      nonce_str: nonceStr,    };    params.sign = makeSign(params, WX_CONFIG.api_key);    const wxRes = await axios.post(      'https://api.mch.weixin.qq.com/pay/orderquery',      toXml(params),      { headers: { 'Content-Type': 'text/xml' } }    );    const wxData = await fromXml(wxRes.data);    // 微信已支付,更新本地    if (wxData.trade_state === 'SUCCESS') {      await updateLocalOrder(orderId, { status: 'paid', transactionId: wxData.transaction_id });      return res.json({ code: 200, msg: 'success', data: { status: 'paid' } });    }    res.json({ code: 200, msg: 'success', data: { status: wxData.trade_state } });  } catch (err) {    console.error('查询失败', err);    res.json({ code: 500, msg: '查询失败' });  }});// ==================== 模拟数据库操作 ====================async function saveLocalOrder(order) { /* 实际项目中写入数据库 */ console.log('创建订单', order); }async function getLocalOrder(orderId) { /* 实际项目中从数据库读取 */ return null; }async function updateLocalOrder(orderId, data) { /* 实际项目中更新数据库 */ console.log('更新订单', orderId, data); }module.exports = router;

8.3 完整支付回调代码

// server/routes/notify.jsconst express = require('express');const router = express.Router();const crypto = require('crypto');const xml2js = require('xml2js');const WX_CONFIG = {  appid: process.env.WX_APPID,  mch_id: process.env.WX_MCH_ID,  api_key: process.env.WX_API_KEY,};router.post('/notify', async (req, res) => {  try {    // 1. 解析 XML    const xml = req.body.toString('utf8');    const parser = new xml2js.Parser({ explicitArray: false });    const data = (await parser.parseStringPromise(xml)).xml;    console.log('微信回调:', JSON.stringify(data));    // 2. 验证签名    const { sign, ...rest } = data;    const verifySign = (params) => {      const str = Object.keys(params).sort()        .filter(k => params[k])        .map(k => `${k}=${params[k]}`)        .join('&') + `&key=${WX_CONFIG.api_key}`;      return crypto.createHash('md5').update(str, 'utf8').digest('hex').toUpperCase();    };    if (verifySign(rest) !== sign) {      console.error('❌ 签名验证失败');      return res.send('<xml><return_code><![CDATA[FAIL]]></return_code></xml>');    }    // 3. 支付失败    if (data.return_code !== 'SUCCESS') {      console.error('支付失败:', data.return_msg);      return res.send('<xml><return_code><![CDATA[FAIL]]></return_code></xml>');    }    // 4. 更新订单(幂等处理)    const order = await getLocalOrder(data.out_trade_no);    if (order && order.status !== 'paid') {      await updateLocalOrder(data.out_trade_no, {        status: 'paid',        transactionId: data.transaction_id,        paidAmount: parseInt(data.total_fee) / 100,      });      console.log('✅ 订单更新成功:', data.out_trade_no);    }    // 5. 返回 SUCCESS    res.send('<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>');  } catch (err) {    console.error('回调异常:', err);    res.send('<xml><return_code><![CDATA[FAIL]]></return_code></xml>');  }});// 辅助函数async function getLocalOrder(orderId) { return null; }async function updateLocalOrder(orderId, data) { console.log('更新订单', orderId, data); }module.exports = router;

九、完整流程总结

9.1 文字版流程

┌─────────────────────────────────────────────────────────────────┐│                        小程序支付完整流程                         │├─────────────────────────────────────────────────────────────────┤│                                                                  ││  【前端】UniApp 小程序                                            ││    │                                                              ││    ├── 1. 获取用户 openid(通过 uni.login + 后端交换)              ││    │                                                              ││    ├── 2. 调用后端创建订单接口                                     ││    │                                                              ││    └── 3. 拿到支付参数后调用 uni.requestPayment()                  ││         ├── timeStamp (字符串)                                   ││         ├── nonceStr (随机字符串)                                 ││         ├── package (prepay_id=xxx)                              ││         ├── signType (MD5)                                       ││         └── paySign (签名)                                       ││                                                                  ││  【后端】Node.js 服务                                             ││    │                                                              ││    ├── 1. 创建订单接口                                            ││    │   ├── 生成 out_trade_no                                     ││    │   ├── 调用微信统一下单 API                                    ││    │   ├── 获取 prepay_id                                        ││    │   ├── 二次签名                                               ││    │   └── 返回支付参数给前端                                      ││    │                                                              ││    ├── 2. 支付回调接口(notify_url)                               ││    │   ├── 接收微信异步通知                                         ││    │   ├── 验证签名                                               ││    │   ├── 更新订单状态                                           ││    │   └── 返回 SUCCESS                                          ││    │                                                              ││    └── 3. 订单查询接口                                            ││        ├── 前端查单兜底                                           ││        └── 后端主动查询微信                                        ││                                                                  │└─────────────────────────────────────────────────────────────────┘

9.2 各环节注意事项汇总

环节
注意事项
金额
必须是整数(分),禁止用浮点数
签名
参数名大小写敏感,package 必须带 prepay_id= 前缀
回调
必须 HTTPS、必须返回 XML、必须先返回 SUCCESS 再处理业务
防重
前端加支付锁、后端幂等处理
掉单
支付后主动查单兜底
openid
必须通过 code 换取,不能前端生成
IP白名单
微信商户平台配置服务器出口 IP

9.3 快速自检清单

□ manifest.json 已配置 appid□ 微信开发者工具已开启支付功能□ 后端接口已配置 HTTPS□ 商户号已绑定小程序 appid□ notify_url 已配置且可访问□ API 密钥已正确配置□ 金额计算已用整数(分)□ 前端已添加支付防重锁□ 后端已实现幂等处理□ 已实现查单兜底机制

结语

小程序支付对接并不复杂,关键点就三个:

  1. 后端完成所有签名和订单创建

  2. 前端只负责调起支付(uni.requestPayment)

  3. 通过回调 + 查单双重保证订单状态正确

遇到问题先看报错信息,再对照本文的排查表,基本都能解决。祝对接顺利! 🚀

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-05-29 19:16:38 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/676527.html
  2. 运行时间 : 0.090081s [ 吞吐率:11.10req/s ] 内存消耗:4,770.11kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=0b8b512e435a2bfd3eaa9a6a5decd83c
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000517s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000656s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000279s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000281s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000582s ]
  6. SELECT * FROM `set` [ RunTime:0.000195s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000517s ]
  8. SELECT * FROM `article` WHERE `id` = 676527 LIMIT 1 [ RunTime:0.000466s ]
  9. UPDATE `article` SET `lasttime` = 1780053398 WHERE `id` = 676527 [ RunTime:0.007173s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000239s ]
  11. SELECT * FROM `article` WHERE `id` < 676527 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000467s ]
  12. SELECT * FROM `article` WHERE `id` > 676527 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001186s ]
  13. SELECT * FROM `article` WHERE `id` < 676527 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000720s ]
  14. SELECT * FROM `article` WHERE `id` < 676527 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000633s ]
  15. SELECT * FROM `article` WHERE `id` < 676527 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000901s ]
0.091800s