微信支付接入全流程:JSAPI支付、小程序支付与H5支付

微信支付三种模式


1️⃣ JSAPI支付(微信内H5)

JSAPI支付有两种调用方式:

方式 特点 适用场景
方式A:JSSDK 需引入wxjssdk,需wx.config配置签名 需要更多微信能力(分享、扫码等)
方式B:WeixinJSBridge 无需引入SDK,直接调用微信内置桥 只需要支付,代码更简单

方式A:JSSDK(wx.chooseWXPay)

javascript 复制代码
// 1. 引入JSSDK
// <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

// 2. 后端提供签名(appId、timestamp、nonceStr、signature)
wx.config({
  appId: 'xxx',
  timestamp: '时间戳',
  nonceStr: '随机串',
  signature: '后端签名',
  jsApiList: ['chooseWXPay']
});

// 3. 发起支付
wx.ready(() => {
  wx.chooseWXPay({
    timestamp: '时间戳',
    nonceStr: '随机串',
    package: 'prepay_id=xxx',
    signType: 'RSA',
    paySign: '签名',
    success: () => checkOrderStatus(orderId),
    fail: () => showCancelResult()
  });
});

方式B:WeixinJSBridge(推荐简单场景)

javascript 复制代码
// 后端返回支付参数后,直接调用
function onBridgeReady() {
  WeixinJSBridge.invoke('getBrandWCPayRequest', {
    appId: 'xxx',           // 后端返回
    timeStamp: '时间戳',    // 后端返回
    nonceStr: '随机串',     // 后端返回
    package: 'prepay_id=xxx', // 后端返回
    signType: 'RSA',        // 后端返回
    paySign: '签名'         // 后端返回
  }, function(res) {
    if (res.err_msg === 'get_brand_wcpay_request:ok') {
      // 支付成功,但需查询后端确认
      checkOrderStatus(orderId);
    } else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
      // 用户取消
      showCancelResult();
    } else {
      // 支付失败
      showFailResult();
    }
  });
}

// 判断是否在微信环境
if (typeof WeixinJSBridge === 'undefined') {
  document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else {
  onBridgeReady();
}

JSAPI完整流程(两种方式通用)

复制代码
前端                    后端                    微信
 │                      │                      │
 ├─ 1.点击支付 ────────→│                      │
 │                      ├─ 2.统一下单 ────────→│
 │                      │← 3.prepay_id ────────┤
 │← 4.签名参数 ─────────┤                      │
 ├─ 5.调起支付 ──────────────────────────────→│
 │← 6.用户完成/取消 ──────────────────────────┤
 │                      │← 7.异步通知 ─────────┤
 │                      ├─ 8.验签更新订单 ─────│
 │                      │                      │
 ├─ 9.查询订单状态 ────→│                      │
 │← 10.返回结果 ────────┤                      │
 ├─ 11.显示结果         │                      │

2️⃣ 小程序支付

完整流程:

ini 复制代码
前端                    后端                    微信
 │                      │                      │
 ├─ 1.点击支付 ────────→│                      │
 │                      ├─ 2.统一下单 ────────→│
 │                      │  (trade_type=JSAPI)  │
 │                      │← 3.prepay_id ────────┤
 │← 4.签名参数 ─────────┤                      │
 ├─ 5.调起支付 ──────────────────────────────→│
 │← 6.用户完成/取消 ──────────────────────────┤
 │                      │← 7.异步通知 ─────────┤
 │                      ├─ 8.验签更新订单 ─────│
 │                      │                      │
 ├─ 9.查询订单状态 ────→│                      │
 │← 10.返回结果 ────────┤                      │
 ├─ 11.显示结果         │                      │

前端代码:

javascript 复制代码
// 1. 调用后端接口获取支付参数
async function handlePay(orderId) {
  const res = await api.createPay(orderId);
  
  // 2. 调用微信支付
  wx.requestPayment({
    timeStamp: res.timeStamp,     // 后端返回
    nonceStr: res.nonceStr,       // 后端返回
    package: res.package,         // 后端返回,格式:prepay_id=xxx
    signType: res.signType,       // 后端返回,固定RSA
    paySign: res.paySign,         // 后端返回
    success: () => {
      // 支付完成,查询后端确认结果
      checkOrderStatus(orderId);
    },
    fail: (err) => {
      if (err.errMsg === 'requestPayment:fail cancel') {
        // 用户取消
        showCancelResult();
      } else {
        // 支付失败
        showFailResult();
      }
    }
  });
}

// 3. 轮询查询订单状态
function checkOrderStatus(orderId) {
  let count = 0;
  const timer = setInterval(async () => {
    const res = await api.getOrderStatus(orderId);
    if (res.status === 'PAID') {
      clearInterval(timer);
      showSuccessPage();
    }
    if (++count >= 10) {
      clearInterval(timer);
      showPendingPage(); // 处理中
    }
  }, 2000);
}

小程序支付与JSAPI的区别:

对比项 小程序支付 JSAPI支付
运行环境 微信小程序内 微信内H5页面
调用API wx.requestPayment wx.chooseWXPay 或 WeixinJSBridge
是否需要SDK 不需要(小程序内置) JSSDK方式需要,WeixinJSBridge不需要
签名方式 RSA RSA
返回结果 success/fail回调 res.err_msg判断

3️⃣ H5支付(微信外浏览器)

流程:

javascript 复制代码
// 1. 获取支付链接
const res = await api.createH5Pay(orderId);
const mwebUrl = res.mweb_url;

// 2. 保存订单信息(支付后返回时查询)
localStorage.setItem('pendingOrderId', orderId);

// 3. 跳转到微信支付
window.location.href = mwebUrl;

// 4. 支付完成后微信跳回 redirect_url
// 在回调页查询订单状态
window.onload = async () => {
  const orderId = localStorage.getItem('pendingOrderId');
  if (orderId) {
    localStorage.removeItem('pendingOrderId');
    checkOrderStatus(orderId);
  }
};

公共逻辑:轮询查询订单状态

javascript 复制代码
function checkOrderStatus(orderId) {
  let count = 0;
  const timer = setInterval(async () => {
    const res = await api.getOrderStatus(orderId);
    if (res.status === 'PAID') {
      clearInterval(timer);
      showSuccessPage();
    }
    if (++count >= 10) {
      clearInterval(timer);
      showPendingPage(); // 处理中
    }
  }, 2000);
}

前端开发清单

模块 开发内容
公共 ① 订单状态查询接口 ② 轮询逻辑 ③ 结果页面(成功/失败/处理中)
JSAPI-A JSSDK配置 + wx.chooseWXPay
JSAPI-B WeixinJSBridge.invoke(无需SDK)
小程序 wx.requestPayment
H5 跳转mweb_url + 回调页查询

后端接口清单

bash 复制代码
POST /api/pay/create        // 创建支付(返回签名参数或mweb_url)
GET  /api/pay/status/:id    // 查询订单支付状态
相关推荐
miss6 小时前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan7 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真7 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment7 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan7 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么7 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模
上海懒图科技8 小时前
工厂厂区电子地图定位导航:厂区人车精准定位,安全合规双保障
前端·arcgis·vue
西安小哥8 小时前
端侧跑大模型,真正的门槛不在参数量:一次 596 秒到 10 秒的压缩路径复盘
前端·人工智能
陈随易8 小时前
Cloudflare 出钱,Vite 团队挑人,44 个维护者分 30 万美元
前端·后端·程序员
恋猫de小郭9 小时前
Flutter THLC 的 WebView 滚动终于从 70 FPS 提升到 120 FPS
android·前端·flutter