微信支付接入全流程: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    // 查询订单支付状态
相关推荐
OpenTiny社区1 小时前
React 正式登场!GenUI SDK v1.4.0 三框架渲染、出码与 Agent 生态重磅升级~
前端·ai编程
试图让你心动1 小时前
【无标题】
前端·javascript·vue.js
Hilaku1 小时前
为什么每个前端都应该拥有一个自己的独立博客?
前端·javascript·程序员
燕落南枝1 小时前
CSS 后代选择器与子代选择器:从入门到实战
前端·css
Amos_Web1 小时前
Rspack 源码解析(二十八):HtmlRspackPlugin 如何把模板变成带资源标签的最终产物
前端
马可家的菠萝2 小时前
个人知识库怎么建?从一个正在学的技术主题开始
前端·笔记·知识管理·个人知识库
几何心凉2 小时前
端到端具身交互智能正式上线:让 AI 通过屏幕和机器人,真正走进现实世界
前端·人工智能·实时互动·机器人·交互
木圭的AI时代指南2 小时前
实测 MiniMax M3.1 Flash:同一道 Three.js 大题,两个 agent 差出 4.6 倍
开发语言·javascript·ecmascript
西红柿炖牛腩3542 小时前
3D 模型压缩脚本又报错又配环境?换个不用维护的方案
javascript·3d·性能优化