Vue3问题:如何实现微信扫码支付?全面!

前端功能问题系列文章,点击上方合集↑

序言

大家好,我是大澈!

本文约2000+字,整篇阅读大约需要5分钟。

本文主要内容分三部分,第一部分是需求分析,第二部分是实现步骤,第三部分是问题详解。

如果您只需要解决问题,请阅读第一、二部分即可。

如果您有更多时间,进一步学习问题相关知识点,请阅读至第三部分。

1. 需求分析

点击微信扫码支付按钮,会弹出扫码支付弹框,在弹框中部显示一个微信支付的二维码。

用户打开微信扫码并支付成功后,就会关闭弹框,弹出成功消息提示,并刷新表格数据,更新对应订单的支付状态,置灰微信扫码支付按钮。

用户点击弹框内的取消按钮,就会隐藏弹框。

2. 实现步骤

2.1 准备工作(了解即可)

  • 登录微信公众平台,获取微信公众号开发者ID(AppID)

  • 登录微信支付商户平台,申请Api证书、设置APIv3秘钥。当然,这里有一个前提,必须要有商家的营业证书,否则无法认证和申请。

  • 获取微信支付商户号、获取商户证书序列号。

2.2 编写后端接口(了解即可)

  • pom.xml文件中,引入微信支付相关依赖。
  • application.xml文件中,配置上面在准备工作中获取的微信支付相关配置信息。
  • 新建一个微信支付配置类WechatConfig,映射配置文件中配置的参数。

  • 编写一个微信支付下单请求参数WxOrderDTO类。

    具体参数详情见官方文档:https://pay.weixin.qq.com/docs/merchant/apis/native-payment/direct-jsons/native-prepay.html

  • 编写一个微信返回通知结果集WxResultDTO类。

    具体参数详情见官方文档:https://pay.weixin.qq.com/docs/merchant/apis/native-payment/payment-notice.html

  • 编写一个微信支付工具类WxPayUtils,在其中定义一个获取HttpClient实例的公共方法getClient,通过商户号和序列号,以及加载秘钥文件和证书文件,生成对应的HttpClient实例。

  • 编写调用微信支付接口的WxPayService业务类,在其中编写一个Native支付的统一下单方法CreateNativeOrder

  • 编写一个微信支付的WxPayController类,在其中编写一个微信支付下单的方法nativeWxPay

    值得注意的是,请求参数WxOrderDTO中的notify_url参数对应的地址,就是微信支付返回通知的回调地址。

  • 编写一个带条件分页查询订单列表的接口,用来查询对应订单的支付状态。

    这个比较简单,按个人业务需求编写,此处不再赘述。

  • 编写一个微信支付返回通知回调方法wxCallBack,在这里对微信返回的通知信息进行了签名验证、参数解密,判断通知数据中交易状态为成功后,修改订单状态。

  • 扩展:申请微信退款功能实现详细,基本类同微信支付下单流程,此处不再赘述。

    退款参数详情见官方文档:https://pay.weixin.qq.com/docs/merchant/apis/native-payment/create.html

2.3 编写前端

在真实项目中,前端对于微信扫码支付所做的操作并不多。

无非就是调用后端微信扫码支付下单的接口,请求成功后在页面渲染微信支付二维码。

当用户完成支付操作后,利用定时器轮循查询订单支付状态,从而判断当用户支付成功时,刷新数据并重新渲染页面。

详细实现步骤如下:

  • 编写扫码支付二维码弹框。
xml 复制代码
<template>
  <!-- 扫码支付二维码弹框 -->
  <div>
    <div style="text-align: center;">
      <!-- 使用了Qrcode库来生成二维码,此处不再赘述 -->
      <qrcode
        :text="form.urlCode"
        :width="300"
        :logo="require('@/assets/img/logo.png')"
      />
    </div>
    <div>
      <el-button @click="close">取消</el-button>
    </div>
  </div>
</template>
  • 在API文件中定义2个接口。
javascript 复制代码
// 查询订单支付状态
export const getDetApi = ({ params }: PropsData): any => {
  return fetch({ url:  `/pay/${params.id}`, method: 'get', params })
}

// 微信扫码支付下单接口
export const nativeWxPayApi = ({ params }: PropsData): any => {
  return fetch({ url: `/pay/nativeWxPay/${params.id}`, method: 'get' })
}
  • 编写微信扫码支付方法,在点击微信扫码支付按钮时调用。
scss 复制代码
// 微信扫码支付
async function getNativeWxPayOrder() {
  if (props.info) {
    // 当前订单的id
    const id = (props.info as any).id

    try {
      // 调用微信扫码支付下单接口
      const res = await nativeWxPayApi({
        params: {
          id: id
        }
      })

      if (res) {
        // 渲染后端返回的微信支付二维码
        form['urlCode'] = res.result.code_url
        // 刷新订单状态
        await getOrderStatus()
      }
    } catch (e) {
      console.log(e)
    }
  }
  • 编写查询订单支付状态方法,在调用微信扫码支付接口完成后调用。
typescript 复制代码
// 获取订单支付状态
const getOrderStatus = async() => {
  const id = (props.info as any).id
  const params = {
    params: {
      id: id
    }
  }

  // 使用定时器循环请求查询订单支付状态接口,直到返回支付成功为止
  const myStateInterval = setInterval(async () => {
    // 调用查询订单支付状态接口
    const res = await getDetApi(params)

    if (res.status === 200) {
      // 如果订单支付状态显示为已支付
      if (res.result['status'] === 1) {
        // 清除定时器
        clearInterval(myStateInterval)
        // 消息通知
        emit('success', '成功')
        // 关闭弹框,刷新数据
        close()
      }
    }
  }, 3000)
}

3. 问题详解

3.1 后端接口代码编写细节

后端微信支付下单和申请退款接口详细,请参考视频教程:https://www.bilibili.com/video/BV1eb4y187Qy?p=18&spm_id_from=pageDriver&vd_source=2571ea6a1d02797fe7590325786e2e84

一切版权归原作者所有,如有侵权请联系删除。

3.2 用到文档地址整理

  • 微信支付API文档:https://pay.weixin.qq.com/docs/merchant/apis/native-payment/direct-jsons/native-prepay.html
  • 微信商户平台:https://pay.weixin.qq.com/
  • 微信公众平台:https://mp.weixin.qq.com

结语

建立这个平台的初衷:

  • 打造一个仅包含前端问题的问答平台,让大家高效搜索处理同样问题。
  • 通过不断积累问题,一起练习逻辑思维,并顺便学习相关的知识点。
  • 遇到难题,遇到有共鸣的问题,一起讨论,一起沉淀,一起成长。

感谢关注微信公众号:"程序员大澈",然后加入问答群,让我们一起解决实现所有BUG!

相关推荐
AI_零食38 分钟前
番茄钟鸿蒙PC Electron框架完成:状态机、定时器管理与专注力工具设计
前端·javascript·华为·electron·开源·鸿蒙·鸿蒙系统
提子拌饭13339 分钟前
逛三园游戏——基于鸿蒙PC Electron框架实现
前端·javascript·游戏·华为·electron·鸿蒙
爱因斯坦乐1 小时前
Vue项目整合
前端·javascript·vue.js
FlyWIHTSKY1 小时前
TS、TSX、JS、JSX 文件扩展名详解
开发语言·javascript·ecmascript
ct9782 小时前
组件间的通信
前端·javascript·vue.js
左手吻左脸。3 小时前
Vue 全栈面试题大全(2026 最新版最详细)
前端·javascript·vue.js
两个西柚呀3 小时前
js中的同步和异步,三种处理异步任务的方式
前端·javascript
小新1104 小时前
最简单但完整的 Vue 响应式示例(一个简单的计数器按钮)
前端·javascript·vue.js
川冰ICE4 小时前
JavaScript进阶④|Symbol与元编程,对象的隐藏身份
开发语言·javascript·ecmascript
水煮白菜王4 小时前
开源 AI 桌宠 Clawd on Desk:让 Claude Code 的状态从终端‘蹦‘到桌面
javascript·人工智能·开源