首页 > 其他分享 >vue+laravel使用微信Natvite支付

vue+laravel使用微信Natvite支付

时间:2024-11-25 18:13:03浏览次数:10  
标签:laravel vue Natvite 微信 time 支付 total data payInfo

Native支付是指商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。适用于PC网站、实体店单品或订单、媒体广告支付等场景
1.先阅读微信支付接入前的准备文档 文档连接:Native支付接入前准备
2.php下载插件 composer require wechatpay/wechatpay
3.需要把证书文件下载下来用于签名验证。下载的签名文件有例如
image
4.需要用到的参数配置到env环境变量中 如下 image

5.代码实现

获取支付二维码链接
/**
     * 微信二维码预支付
     * @param string $total 价格
     * @param string $outTradeNo 商户订单号
     * @param int $duration 二维码有效时长 单位:秒
     * @return array 返回二维码链接
     */
    public static function wxNativePrePay(string $total, string $outTradeNo, $duration = 180)
    {
        try {
            $config = Common::get_platform_payInfo();
            $time = \time();
            $time_expire = $time + $duration;
            $rfc3339_time = date(DATE_RFC3339, $time_expire);
            $total = intval(bcmul($total, 100));

            $payInfo = [
                'out_trade_no' => $outTradeNo,
                'appid' => $config['appId'],
                'description' => '支付维修费用',
                'total' => $total,
                'time_expire' => (string)$rfc3339_time,
            ];

            $instance = Common::wxPayObj();
            $resp = $instance
                ->chain('v3/pay/transactions/native')
                ->post(['json' => [
                    'mchid' => $config['merchantId'],
                    'out_trade_no' => $payInfo['out_trade_no'],
                    'time_expire' => $payInfo['time_expire'],
                    'appid' => $config['appId'],
                    'description' => $payInfo['description'],
                    'notify_url' => $config['notify_url'],
                    'amount' => [
                        'total' => $payInfo['total'],
                        'currency' => 'CNY'
                    ],
                ]]);
            $data = [];
            $data['code'] = (int)$resp->getStatusCode();
            $data['body'] = $resp->getBody();
            return $data;

        } catch (\Exception $exception) {
            if ($exception instanceof RequestException && $exception->hasResponse()) {
                $message = "错误回复:" + $exception->getResponse() + "错误码:" + $exception->getResponse()->getStatusCode();
                +"错误原因" + $exception->getResponse()->getReasonPhrase();
                Log::info($message);
            }
            return [];
        }
    }
common只使用的方法
public static function  get_platform_payInfo() {
        $data['merchantPrivateKeyFilePath'] = env('MERCHANT_FILE_PATH');
        $data['platformCertificateFilePath'] = env('PLATFORM_FILE_PATH');
        $data['merchantId'] = env('WX_MERCHANT_ID');
        $data['merchantCertificateSerial'] = env('CERTIFICATE_SERIAL');
        $data['appId'] = env('WX_APP_ID');
        $data['appSecret'] = env('WX_APP_SECRET');
        $data['notify_url'] = env('WX_NOTIFY_URL');
        $data['api_key'] = env('WX_API_KEY');
        return $data;
    }

    public static function wxPayObj()
    {
        try {
           $payInfo = self::get_platform_payInfo();
            // 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
            $merchantPrivateKeyInstance = Rsa::from($payInfo['merchantPrivateKeyFilePath'], Rsa::KEY_TYPE_PRIVATE);
            // 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名
            $platformPublicKeyInstance = Rsa::from($payInfo['platformCertificateFilePath'], Rsa::KEY_TYPE_PUBLIC);
            // 从「微信支付平台证书」中获取「证书序列号」
            $platformCertificateSerial = PemUtil::parseCertificateSerialNo($payInfo['platformCertificateFilePath']);
            // 构造一个 APIv3 客户端实例
            $instance = Builder::factory([
                'mchid'      => $payInfo['merchantId'],
                'serial'     => $payInfo['merchantCertificateSerial'],
                'privateKey' => $merchantPrivateKeyInstance,
                'certs'      => [
                    $platformCertificateSerial => $platformPublicKeyInstance,
                ],
            ]);
            return $instance;
        } catch (\Exception $e) {
            Log::info("返回微信支付对象失败", $e);
            return false;
        }
    }

前端vue DEMO

需要用的的插件 qrcode

点击查看代码
<template>
  <div class="center">
    <el-button type="primary" @click="toWxPrePay">支付</el-button>
    <el-dialog title="支付" :visible.sync="payVisible" width="30%">
      <div class="qrcode_box">
        <canvas id="canvas" ref="qrcodeCanvas" class="qrcode"></canvas>
        <div style="color: #409EFF">请使用微信支付</div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {wxPayInfo} from "@/api/teacher";
import QRCode from "qrcode";
import {wxTransactions} from "@/api/wxAccounts";

export default {
  name: "add",
  data() {
    return {
      payVisible: false,
      codeUrl: '',
      outTradeNo: '',
      intervalId: null,
    }

  },
  destroyed() {
    this.stopPolling()
  },
  methods: {

    toWxPrePay() {
      let total = "0.01" //这里是要付的价格
      wxPayInfo({
        userId: localStorage.getItem("ID"),
        teacherId: 1,
        total: total
      }).then(res => {
        this.codeUrl = res.data['code_url']
        this.outTradeNo = res.data['out_trade_no']
        this.payVisible = true
        this.$nextTick(() => {
          const canvas = document.getElementById('canvas')
          console.log("这是收到的coderUrl", this.codeUrl)
          var text = this.codeUrl
          const ctx = canvas.getContext('2d')
          QRCode.toCanvas(canvas, text, error => {
            if (error) console.log(error)
          })
          this.startPolling()
        })
      })
    },
    startPolling() {
      this.intervalId = setInterval(this.interPaymentWx, 2000); //每两秒更新一次
    },
    stopPolling() {
      if (this.intervalId) clearInterval(this.intervalId)
    },
    //查询订单状态
    interPaymentWx() {
      wxTransactions({
        out_trade_no: this.outTradeNo
      }).then(res => {
        let trade_state = res.data['trade_state']
        if (trade_state === 'SUCCESS') {
          this.$message({
            message: '支付成功',
            type: 'success'
          })
         this.payVisible = false
          this.stopPolling()
        }
      })
    },
  }
}
</script>


<style scoped lang="scss">
.qrcode_box {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  .qrcode {
    width: 270px !important;
    height: 270px !important;
  }
}
</style>

标签:laravel,vue,Natvite,微信,time,支付,total,data,payInfo
From: https://www.cnblogs.com/spinachead/p/18568273

相关文章

  • 使用 Vue 2 和 ECharts 构建 3D 柱状图
    使用Vue2和ECharts构建3D柱状图在现代前端开发中,Vue.js是一个非常流行的框架,它提供了强大的响应式数据绑定和组件化开发,使得前端开发更加灵活高效。而ECharts是一个开源的可视化图表库,具有强大的功能支持,能够轻松生成交互式和美观的数据可视化图表。结合Vue和......
  • Vue 单页应用(SPA)与多页应用(MPA)设计
    Vue单页应用(SPA)与多页应用(MPA)设计在前端开发中,Vue是一个非常受欢迎的框架,因其高效、灵活而被广泛使用。而在Vue项目中,我们经常会遇到单页应用(SPA)和多页应用(MPA)这两种设计模式。今天,我们就来聊聊这两者的区别、优缺点以及如何在Vue中实现它们。一、什么是单页应用(SP......
  • Vue3.0 实操学习笔记
    安装 node.js安装 https://nodejs.org/en安装后执行node-v查看是否有异常以及npm-v查看是否异常调整为淘宝镜像,cnpm-v查看是否异常npminstall-gcnpm--registry=https://registry.npm.taobao.orgVue安装以及安装脚手架 vue-V查看是否异常cnpmi-......
  • 推荐 vue 最好用非常强大表格组件 vxe-table,vue 哪个表格组件好用
    vxe-table是一个全功能vue表格库,非常强大的功能基本可以满足对表格对表格的一切需求。不管是普通列表,大数据列表。可编辑表格,数据校验、Excel单元格选择、复制粘贴等。。。官网:https://vxetable.cngitee安装npminstallvxe-pc-ui@4.3.5vxe-table@4.9.6//...import......
  • Vue Devtools的下载和安装
    1.下载下载地址:https://github.com/vuejs/vue-devtools/tree/v5.1.1 下载下来zip包。解压到指定文件夹 2.安装依赖在这个目录,执行npminstall命令进行依赖安装 3.修改配置打开解压目录vue-devtools-master下的shells/Chrome/manifest.json文件,将代码"persistent":fal......
  • (系列十二)Vue3+.Net8实现用户登录(超详细登录文档)
    说明  该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发)。   该系统文章,我会尽量说的非常详细,做到不管新手、老手都能看懂。   说明:OverallAuth2.0是一个简单、易懂、功能强大的权限+可视化流程管理系统。友情提醒:本篇文章是属于系......
  • pnpm -F @opentiny/tiny-engine-controller -F @opentiny/tiny-engine-dsl-vue build
    pnpm-F@opentiny/tiny-engine-controller-F@opentiny/tiny-engine-dsl-vuebuild命令的作用是使用pnpm包管理器对指定的工作区包进行构建。具体来说:pnpm:这是Node.js的包管理器,类似于npm,但更高效,支持工作区(workspace)管理。-F或--filter:这是一个选项,用于筛选特定的工......
  • Vue3+Typescript+Axios+.NetCore实现导出Excel文件功能
    前端代码//导出ExcelconstexportMaintenanceOrderSettlementItemExcelClick=async()=>{leturl=`${VITE_APP_API_URL}/api/app/maintenance/settlement-service-item/${currentMaintenanceOrderId.value}/${currentMaintenanceOrderSettlementRow.value.id}`;......
  • Vue基础知识—— v-model、watch、computed
    接上一篇Vue知识点​想要学习更多前端知识:点击Web前端专栏 目录一、 双向数据绑定指令v-model(实时渲染)二、数据变动侦听器watch 三、计算属性 computed一、 双向数据绑定指令v-model(实时渲染) 在Vue.js中,v-model是一个指令,用于实现双向数据绑定。它可以在表单......
  • Docker:Docker搭建Jenkins并共用宿主机Docker部署服务(三)构建Vue前端服务
    前言继续完成前端服务部署,Jenkins的搭建与插件安装可以观看上一篇文章:https://www.cnblogs.com/nhdlb/p/18561435新建视图方便将整个项目的前端和后端整合起来(之前的文章都已经创建,这里就不用再创建啦!)新建任务选择视图创建项目(任务)任务配置项目结构这里我先介绍下项......