Laravel7 + easyWeChat 实现微信公众号支付功能
注册服务号,需进行微信认证,此时需缴费 300 元/年,必须是认证成功的服务号才能开通微信支付。
注册微信支付商户号
1、登录 https://pay.weixin.qq.com/index.php/core/home/login?return_url=https%3A%2F%2Fpay.weixin.qq.com%2Findex.php%2Fextend%2Fpay_setting%2Fma,
点击 接入微信,点击 注册微信支付商户号 ,按步骤 创建申请单–填写商户资料–确认提交 即可。 <按提示进行操作即可,步骤无比繁琐>
2、管理员微信号关注 微信支付商家助手 ,以上操作步骤完成并通过后,商家助手会收到 入驻申请进展通知---待签约 ,用管理员手机点进去,扫脸确认签约即可,完成后商家助手会收到 入驻成功 信息。
3、接下来完成 APPID授权管理,登录到微信服务号首页,找到 设置与开发---接口权限,在右边找到 微信支付接口---未获得,点击 申请。在 待关联商户号 一栏中,点击 确认 ,同意授权即可。
此时在 已关联商户号 一栏中显示对应内容,返回 接口权限 页面,查看右边的 微信支付接口 显示 已获得。
微信支付商户后台配置
1、微信商户平台(pay.weixin.qq.com)–>账户中心–>账户设置–>API安全–>设置API密钥,密钥需下载下来放到项目的根目录。接下来设置 APIv2 秘钥、设置 APIv3 秘钥。

2、产品中心–>开发配置–>支付配置,在此添加 JSAPI支付授权目录,如下图所示:

3、关联服务号,如下图:

4、登录微信公众服务号后台,对公众号进行功能设置,如下图:

微信支付功能开发
1、打开 easyWeChat 官网,找到 Laravel 5 拓展包,按步骤安装 laravel-wechat。

// 安装easyWeChat包
composer require "overtrue/laravel-wechat:~5.1"// 创建配置文件
php artisan vendor:publish --provider="Overtrue\LaravelWeChat\ServiceProvider"
在
composer.json中显示的laravel-wechat版本号为"overtrue/laravel-wechat": "^5.1",。
在项目的
config文件夹中自动生成wechat.php文件。
2、在 config/wechat.php 中打开微信支付的配置,然后在 .env 文件中做如下配置:
WECHAT_DEBUG=true# 此配置是实现微信公众号登录认证的配置
WECHAT_OFFICIAL_ACCOUNT_APPID='微信公众号的APPID'
WECHAT_OFFICIAL_ACCOUNT_SECRET='微信公众号的开发者密码(AppSecret)'
WECHAT_OFFICIAL_ACCOUNT_TOKEN='随意字符串'WECHAT_PAYMENT_APPID='微信公众号APPID'
WECHAT_PAYMENT_MCH_ID='微信支付商户号'
WECHAT_PAYMENT_KEY='Hubei***********8'
3、添加下单和支付路由:
Route::prefix('order')->group(function () {// 下单Route::post('/', 'OrderController@store');// 支付Route::get('/pay/{id}', 'OrderController@pay');
});
4、创建订单的控制器方法和模型以及数据表 orders
php artisan make:controller OrderControllerphp artisan make:model Models/Order// 模型里面添加黑名单
protected $guarded = [];// orders 表的字段,以下只是范例,可根据需求自行添加
id、customer_id、out_trade_no、status、total_price、created_at、pay_time、updated_at
我的表结构如下:

5、在 Order 控制器里面的 store 方法,代码如下:
use App\Models\Shop\Address;
use App\Models\Shop\Cart;
use App\Models\Shop\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;// 下单
function store(Request $request)
{$carts = Cart::with('product')->where('customer_id', session('wechat.customer.id'))->get();// 防止用户使用微信的后退按钮,重新提交订单,导致出现没有数据的订单if ($carts->isEmpty()) {return ['status' => 0, 'info' => ''];}$count = Cart::count_cart();$total_price = $count['total_price'];DB::beginTransaction();try {//生成订单$order = Order::create(['out_trade_no'=> Order::make_orderNo(),'customer_id' => session('wechat.customer.id'),'total_price' => $total_price,'status' => 1]);//订单地址$address = Address::find($request->address_id);$order->address()->create(['province' => $address['province'],'city' => $address['city'],'area' => $address['area'],'detail' => $address['detail'],'name' => $address['name'],'tel' => $address['tel'],]);$carts = Cart::with('product')->where('customer_id', session('wechat.customer.id'))->get();foreach ($carts as $cart) {//判断库存是否足够if ($cart->product->stock != '-1' and $cart->product->stock - $cart->num < 0) {throw new \Exception('商品' . $cart->product->name . ", 目前仅剩下" . $cart->product->stock . " 件. \n请返回购物车, 修改订单后再下单!");}//削减库存数量if ($cart->product->stock != '-1') {$cart->product->decrement('stock', $cart->num);}//插入订单商品表$order->order_products()->create(['product_id' => $cart->product_id,'num' => $cart->num]);}//清空购物车Cart::where('customer_id', session('wechat.customer.id'))->delete();} catch (\Exception $e) {//echo $e->getMessage();DB::rollback();return ['status' => 0, 'info' => $e->getMessage()];}DB::commit();return ['status' => 1, 'order_id' => $order->id];
}
6、在 Order 控制器里面的 pay 方法,代码如下:
use App\Models\Shop\Order;
use EasyWeChat;// 微信支付
function pay($id)
{$payment = EasyWeChat::payment();// 第 1 步:查询订单并计算金额$order = Order::with('address')->find($id);// 第 2 步:统一下单$result = $payment->order->unify(['body' => '测试支付','out_trade_no' => $order->out_trade_no,'total_fee' => $order->total_price * 100,'notify_url' => 'https://shop.***.com/order/notify', // 支付结果通知网址'trade_type' => 'JSAPI','openid' => session('wechat.customer.openid'),]);// return $result; // 打印$result看是否有结果// 第 3 步:JSSDKif ($result['result_code'] == 'SUCCESS' && $result['return_code'] == 'SUCCESS') {$prepayId = $result['prepay_id'];$jssdk = $payment->jssdk;$json = $jssdk->sdkConfig($prepayId);// return $json; // 打印$json看是否有结果return view('wechat.order.show_pay', compact('order', 'json'));} else {return $result;}
}
接下来,我们来测试一下上述代码,打印 return $result;。打开 微信开发者工具 ,进入商城首页,依次添加商品到购物车、选择地址、下单,会得到如下图结果:

继续测试,打印 return $json;。就在上图结果中刷新地址,你会得到如下结果:

7、在前端页面底部增加 js 调用代码如下:
<script>$(function () {$("#pay").click(function () {if (typeof WeixinJSBridge === 'undefined') {alert('请在微信在打开页面!');return false;}WeixinJSBridge.invoke('getBrandWCPayRequest', {!! json_encode($json) !!}, function (res) {switch (res.err_msg) {case 'get_brand_wcpay_request:cancel':alert('您取消了支付!');break;case 'get_brand_wcpay_request:fail':alert('支付失败!(' + res.err_desc + ')');break;case 'get_brand_wcpay_request:ok':alert('支付成功!');location.href = '/order';break;default:alert(JSON.stringify(res));break;}});})})
</script>
接下来测试是否能唤起微信支付密码窗口,输入密码后显示支付成功。
注:如有出现错误
调用支付 JSAPI 缺少参数 timeStamp,解决办法:在你项目的vendor/overtrue/wechat/src/Payment/Jssdk/Client.php中屏蔽两行代码就行。
public function sdkConfig(string $prepayId): array
{$config = $this->bridgeConfig($prepayId, false);// 屏蔽这两行代码// $config['timestamp'] = $config['timeStamp'];// unset($config['timeStamp']);return $config;
}
如有其他错误,可以在评论区交流。
微信支付回调
1、首先增加支付回调路由,注意此路由应放在 middleware 中间件路由外面,回调路由请求必须是 post
//支付成功回调
Route::namespace('Wechat')->group(function () {Route::post('/order/notify', 'OrderController@notify');
});

2、laravel 框架必须取消回调路由的 csrf 防护。在你项目的 app/Http/Middleware/VerifyCsrfToken.php 中加入如下代码:
protected $except = ['order/notify', // 回调路由取消csrf防护
];
3、回调代码如下:
/*** 微信支付回调方法,修改订单状态* @return mixed*/
function notify()
{$payment = EasyWeChat::payment();$response = $payment->handlePaidNotify(function ($message, $fail) {if ($message['return_code'] === 'SUCCESS' && $message['result_code'] === 'SUCCESS') {// \Log::debug($message);Order::where('out_trade_no', $message['out_trade_no'])->update(['status' => 2, 'pay_time' => Carbon\Carbon::now()]);//更改订单状态//支付后,微信会在此处返回支付状态,就是$message,回调里面打印不出来,可通过写入日志里面查看,支付成功后更改订单状态。当然你也可以进行其他操作。return true;} else {// \Log::debug('我不买了');return $fail('失败');}});return $response;
}
4、最后测试如下:



支付流程总结
1、点击支付按钮,js 提交相应参数到后台支付方法。
2、后台接收请求,往你的订单表里插入一条订单数据,状态为 1,也就是未支付状态。
3、带上这条订单的订单号、价格,请求微信换取 prepay_id。
4、请求微信成功会返回支付所需要的参数,appid,timestamp 等。返回前端 js 调起支付。
5、支付后微信会将支付结果通过回调返回,可根据返回信息修改订单状态。
参考文献:https://learnku.com/articles/37459
相关文章:
Laravel7 + easyWeChat 实现微信公众号支付功能
注册服务号,需进行微信认证,此时需缴费 300 元/年,必须是认证成功的服务号才能开通微信支付。 注册微信支付商户号 1、登录 https://pay.weixin.qq.com/index.php/core/home/login?return_urlhttps%3A%2F%2Fpay.weixin.qq.com%2Findex.php%…...
Linux环境下,针对QT软件工程搭建C++Test单元测试环境的操作指南
文章目录 前言一、安装QT二、安装CTest三、使用QT生成.bdf文件四、创建CTest工程注意事项 前言 CTest是Parasoft公司出品的一款可以针对C/C源代码进行静态分析、单元测试、集成测试的测试工具。本文主要讲解如何在Linux环境下,搭建QT插件版的CTest测试环境。 一、…...
16k+ start 一个开源的的监控系统部署教程
安装条件 Linux或macOS系统 4GB内存 开放 33014、33174、3183端口 1.安装 1、下载源码 首先使用 git 克隆源码到本地 git clone -b main https://github.com/SigNoz/signoz.git && cd signoz/deploy/ 方式1:运行 install.sh 脚本一键安装 ./install.s…...
Mermaid使用教程(绘制各种图)
Mermaid使用教程(绘制各种图) 文章目录 Mermaid使用教程(绘制各种图)简介饼状图简单的例子应用案例 序列图简单案例应用案例另一个应用案例 甘特图简单案例应用案例一个更为复杂的应用案例 Git图简单案例 总结 简介 本文将主要介…...
OpenAI/ChatGPT Plus 支持的虚拟卡有哪些
最近,有关 OpenAI/ChatGPT Plus 需要信用卡的讨论越来越多。在这篇文章中,我将分享一些我在绑定信用卡过程中得到的经验和教训,以及 OpenAI/ChatGPT Plus 支持的卡类型。 不支持的卡 根据 OpenAI 的地区限制,国内和香港的卡都不…...
ARM多核调度器DSU
1. 背景 从A75开始,ARM提出了一个新的多核心管理系统单元,叫做DSU(DynamIQ Shared Unit)。DSU的核心功能是控制CPU内核,使其成簇Cluster使用,簇内每一个核心可以单独开关、调整频率/电压,能效表现更佳,甚至…...
vue解决部署文件缓存方式
问题:系统上线后,除了bug。紧急修复后,发现安卓正常,ios上海市有问题。通过debug后发现,ios上缓存严重。于是想到了打包文件加时间戳的方式来去除缓存。 vue2 配置打包输出文件名方式: const baseUrl &qu…...
游戏开发中的噪声算法
一、噪声 噪声是游戏编程的常见技术,广泛应用于地形生成,图形学等多方面。 那么为什么要引入噪声这个概念呢?在程序中,我们经常使用直接使用最简单的rand()生成随机值,但它的问题在于生成的随机值太“随机”了…...
CodeReview 小工具
大家开发中有没有遇到一个版本开发的非常杂,开发很多个项目,改动几周后甚至已经忘了自己改了些什么,领导要对代码review的时候,理不清楚自己改过的代码,只能将主要改动的大功能过一遍。这样就很容易造成review遗漏&…...
UE5 C++ Slate独立程序的打包方法
在源码版安装目录内找到已编译通过的xxx.exe,(\Engine\Binaries\Win64\xxx.exe),在需要的位置新建文件夹,拷贝源码版Engine内的Binaries、Content、Shaders文件夹到目标文件夹内,将xxx.exe放入对应位置,删除…...
探索设计模式的魅力:一篇文章让你彻底搞懂建造者模式
建造者模式(Builder Pattern)是一种创建型设计模式,旨在将一个复杂对象的创建过程与其表示分离,使得同样的构建过程可以创建不同的表示形式。 主要角色: 产品(Product):表示正在构建…...
Facebook广告投放指南,如何运营多个Facebook广告账户不被封?
许多卖家做广告投放会选择 Facebook 作为主要的业务和产品推广平台。然而,要在这个竞争激烈的平台上脱颖而出并成功拓宽广告覆盖面并不容易,通常情况下大家会运营多个Facebook广告账号,但是很多人因此遭遇Facebook账号被封的情况,…...
音乐人声分离工具:极简的人声和背景音乐分离工具
项目地址:jianchang512/vocal-separate: an extremely simple tool for separating vocals and background music, completely localized for web operation, using 2stems/4stems/5stems models 这是一个极简的人声和背景音乐分离工具,本地化网页操作&a…...
Go语言基础快速上手
1、Go语言关键字 2、Go数据类型 3、特殊的操作 3.1、iota关键字 Go中没有明确意思上的enum(枚举)定义,不过可以借用iota标识符实现一组自增常亮值来实现枚举类型。 const (a iota // 0b // 1c 100 // 100d // 100 (与上一…...
Excel 根据日期按月汇总公式
Excel 根据日期按月汇总公式 数据透视表日期那一列右击,选择“组合”,步长选择“月” 参考 Excel 根据日期按月汇总公式Excel如何按着日期来做每月求和...
使用 crypto-js 进行 AES 加解密操作
在前端开发中,数据的加密和解密是为了保障用户隐私和数据的安全性而常见的任务。AES(Advanced Encryption Standard)是一种对称密钥加密算法,被广泛用于保护敏感信息的传输和存储。本文将介绍 AES 加解密的基本原理,并…...
Vue-30、Vue非单文件组件。
非单文件组件: 一个组件包含n个组件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>非单文件组件</title><script type"text/javascript" src"https://cdn.jsde…...
7-6 实验2_1_判断两数的大小
7-6 实验2_1_判断两数的大小 分数 100 全屏浏览题目 切换布局 作者 scs 单位 北京邮电大学 已知有两个整数,请使用if-else选择结构将它们中的较大数选择出来,存到max变量中;将较小数选择出来,存到min变量中,并将选…...
POKT Network (POKT) :进军百亿美元市场规模的人工智能推理市场
POKT Network(又称 Pocket Network)是一个去中心化的物理基础设施网络(DePIN),它能够协调并激励对任何开放数据源的访问,最初专注于向应用程序和服务提供商提供区块链数据。 自 2020 年主网上线以来&#x…...
【STM32】STM32学习笔记-I2C通信外设(34)
00. 目录 文章目录 00. 目录01. I2C简介02. I2C外设简介03. I2C框图04. I2C基本结构05. 主机发送06. 主机接收07. 软件/硬件波形对比08. 预留09. 附录 01. I2C简介 I2C(Inter-Integrated Circuit)总线是一种由NXP(原PHILIPS)公司开发的两线式…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
