菜鸟-创作你的创作

微信小程序支付包含uniapp方法超详细讲解

下面给你一份 微信小程序支付(含 uni-app)最全、最详细、从零到成品的讲解,涵盖 小程序端、云函数/服务端、uni-app 两种写法、注意事项、常见报错、回调通知、退款 等完整流程。


✅ 微信小程序支付(含 uni-app)超详细教程

核心流程
小程序端下单 → 后端统一下单(生成预支付单)→ 小程序拉起支付 → 支付成功 → 服务端支付回调验证 → 更新订单状态


目录

  1. 必备前置配置
  2. 小程序支付流程图
  3. 小程序端 JS(原生写法)
  4. uni-app 端代码(APP + 小程序同写法)
  5. Node.js 服务端统一下单代码
  6. 支付结果回调(服务端)
  7. 常见坑与错误
  8. 退款示例

1. 📌 必备前置配置

你需要:

✔ 已开通微信支付商户号

✔ 小程序 AppID

✔ 后端服务(Node.js / Java / PHP)

这里示例 Node.js。


2. 📌 小程序支付流程图

用户点击支付  
    ↓  
小程序请求后端下单  
    ↓  
后端调用微信支付统一下单 API  
    ↓  
微信返回 prepay_id  
    ↓  
小程序 wx.requestPayment 调起支付  
    ↓  
支付成功  
    ↓  
微信服务器发送支付回调 → 后端  
    ↓  
后端校验签名并修改订单状态


3. 📌 小程序端代码(原生 WeChat Mini-program)

① 前端发起订单请求

wx.request({
  url: 'https://your-server.com/pay/unifiedorder',
  method: 'POST',
  data: { orderId: '12345' },
  success(res) {
    const pay = res.data;

    wx.requestPayment({
      timeStamp: pay.timeStamp,
      nonceStr: pay.nonceStr,
      package: pay.package,
      signType: pay.signType,
      paySign: pay.paySign,
      success(res) {
        console.log('支付成功', res);
      },
      fail(err) {
        console.log('支付失败', err);
      }
    });
  }
});

返回的 pay 信息来自后端签名。


4. 📌 uni-app 端完整支付写法(小程序 + APP 通用)

uni.request + uni.requestPayment

payOrder(orderId) {
  uni.request({
    url: 'https://your-server.com/pay/unifiedorder',
    method: 'POST',
    data: { orderId },
    success: (res) => {
      const pay = res.data;

      uni.requestPayment({
        provider: 'wxpay',
        timeStamp: pay.timeStamp,
        nonceStr: pay.nonceStr,
        package: pay.package,
        signType: 'RSA',
        paySign: pay.paySign,
        success: res => {
          console.log('支付成功', res);
        },
        fail: err => {
          console.log('支付取消/失败', err);
        }
      });
    }
  });
}

App 端 支付时 provider 必须写 "wxpay"


5. 📌 Node.js 后端统一下单(最全实现)

使用官方 微信支付 v3 API

安装库:

npm i axios crypto

统一下单接口代码(Node.js Koa/Express 都可用)

const axios = require('axios');
const crypto = require('crypto');
const fs = require('fs');

const appId = "你的appid";
const mchId = "你的商户号";
const apiKey = "你的APIv3密钥";

// 私钥文件(apiclient_key.pem)
const privateKey = fs.readFileSync('./cert/apiclient_key.pem');

// 生成签名函数
function sign(method, url, timestamp, nonceStr, body = '') {
  const message = `${method}\n${url}\n${timestamp}\n${nonceStr}\n${body}\n`;

  const signer = crypto.createSign('RSA-SHA256');
  signer.update(message);
  return signer.sign(privateKey, 'base64');
}

exports.unifiedorder = async (req, res) => {
  const { orderId } = req.body;

  const url = '/v3/pay/transactions/jsapi';
  const fullUrl = 'https://api.mch.weixin.qq.com' + url;

  const data = {
    appid: appId,
    mchid: mchId,
    description: "商品描述",
    out_trade_no: orderId,
    notify_url: "https://your-server.com/pay/notify",
    amount: {
      total: 100, // 单位:分
    },
    payer: {
      openid: req.body.openid,
    }
  };

  const timestamp = Math.floor(Date.now() / 1000).toString();
  const nonceStr = crypto.randomBytes(16).toString('hex');
  const bodyStr = JSON.stringify(data);

  const signature = sign('POST', url, timestamp, nonceStr, bodyStr);

  const auth = `WECHATPAY2-SHA256-RSA2048 mchid="${mchId}",nonce_str="${nonceStr}",signature="${signature}",timestamp="${timestamp}",serial_no="你的证书序列号"`;

  const result = await axios.post(fullUrl, data, {
    headers: {
      'Authorization': auth,
      'Content-Type': 'application/json'
    }
  });

  const prepayId = result.data.prepay_id;

  // 生成前端需要的签名
  const payTimestamp = timestamp;
  const payNonceStr = nonceStr;
  const payPackage = `prepay_id=${prepayId}`;
  const paySignString = `${appId}\n${payTimestamp}\n${payNonceStr}\n${payPackage}\n`;

  const paySign = crypto
    .createSign('RSA-SHA256')
    .update(paySignString)
    .sign(privateKey, 'base64');

  res.json({
    timeStamp: payTimestamp,
    nonceStr: payNonceStr,
    package: payPackage,
    signType: 'RSA',
    paySign,
  });
};


6. 📌 微信支付回调通知(必须处理)

微信支付成功后会 POST 到你的:

https://your-server.com/pay/notify

Node.js 代码:

exports.notify = async (req, res) => {
  const { resource, summary } = req.body;

  console.log("支付回调内容:", req.body);

  // 解密 resource.ciphertext
  const decipher = crypto.createDecipheriv(
    'aes-256-gcm',
    apiKey,
    Buffer.from(resource.nonce, 'hex')
  );
  decipher.setAuthTag(Buffer.from(resource.tag, 'hex'));

  const decrypted = JSON.parse(
    decipher.update(resource.ciphertext, 'base64', 'utf8') + decipher.final('utf8')
  );

  console.log("已解密的支付信息:", decrypted);

  // 修改订单状态…
  // updateOrder(decrypted.out_trade_no)

  res.status(200).json({ code: 'SUCCESS' });
};


7. 📌 常见报错与解决方法

错误原因解决
INVALID_REQUEST参数不完整检查 appid, mchid, notify_url
appid 和 openid 不匹配openid 非当前小程序必须用 wx.login 获取
支付调起后无反应前端签名错误重点检查 paySign
prepay_id 已失效5 分钟未使用重签名并重新下单
小程序显示 “商户号未开通小程序支付”商户号未绑定 appid去商户平台绑定

8. 📌 退款示例(Node.js)

exports.refund = async (req, res) => {
  const url = '/v3/refund/domestic/refunds';
  const data = {
    out_trade_no: req.body.orderId,
    out_refund_no: 'refund_' + Date.now(),
    amount: {
      refund: 100,
      total: 100,
      currency: 'CNY'
    }
  };

  // 与统一下单一样:生成签名 → 调用微信 API
};

退出移动版